Không, bạn không thể ghi đè một phương thức không phải ảo. Điều gần nhất bạn có thể làm là ẩn phương thức bằng cách tạo một new
phương thức có cùng tên nhưng điều này không được khuyến khích vì nó phá vỡ các nguyên tắc thiết kế tốt.
Nhưng ngay cả việc ẩn một phương thức cũng không cung cấp cho bạn thời gian thực thi việc gửi đa hình các lệnh gọi phương thức giống như một lệnh gọi phương thức ảo thực sự. Hãy xem xét ví dụ này:
using System;
class Example
{
static void Main()
{
Foo f = new Foo();
f.M();
Foo b = new Bar();
b.M();
}
}
class Foo
{
public void M()
{
Console.WriteLine("Foo.M");
}
}
class Bar : Foo
{
public new void M()
{
Console.WriteLine("Bar.M");
}
}
Trong ví dụ này, cả hai đều gọi M
phương thức print Foo.M
. Như bạn có thể thấy, cách tiếp cận này cho phép bạn có một triển khai mới cho một phương thức miễn là tham chiếu đến đối tượng đó có kiểu dẫn xuất chính xác nhưng ẩn một phương thức cơ sở thì không. phá vỡ tính đa hình.
Tôi khuyên bạn không nên ẩn các phương thức cơ sở theo cách này.
Tôi có xu hướng đứng về phía những người ủng hộ hành vi mặc định của C # rằng các phương thức không phải là ảo theo mặc định (trái ngược với Java). Tôi thậm chí còn đi xa hơn và nói rằng các lớp cũng nên được niêm phong theo mặc định. Việc kế thừa rất khó để thiết kế cho phù hợp và thực tế là có một phương thức không được đánh dấu là ảo cho thấy rằng tác giả của phương pháp đó không bao giờ có ý định ghi đè phương thức.
Chỉnh sửa: "công văn đa hình thời gian thực thi" :
Ý tôi là đây là hành vi mặc định xảy ra tại thời điểm thực thi khi bạn gọi các phương thức ảo. Hãy nói ví dụ rằng trong ví dụ mã trước của tôi, thay vì xác định một phương thức không phải ảo, trên thực tế, tôi đã xác định một phương thức ảo và một phương thức ghi đè thực sự.
Nếu tôi gọi b.Foo
trong trường hợp đó, CLR sẽ xác định chính xác loại đối tượng mà b
tham chiếu trỏ đến Bar
và sẽ gửi lệnh gọi đến M
một cách thích hợp.