2010-09-23 38 views
5

Tôi không hiểu hiện tượng sau đây, ai đó có thể giải thích cho tôi xin vui lòng những gì tôi đã sai?Thừa kế và tính chất tĩnh

public class BaseClass 
{ 
    public BaseClass() 
    { 
     BaseClass.Instance = this; 
    } 

    public static BaseClass Instance 
    { 
     get; 
     private set; 
    } 
} 

public class SubClassA : BaseClass 
{ 
    public SubClassA() 
     : base() 
    { } 
} 

public class SubClassB : BaseClass 
{ 
    public SubClassB() 
     : base() 
    { } 
} 

class Program 
{ 
    static void Main(string[] args) 
    { 
     SubClassA a = new SubClassA(); 
     SubClassB b = new SubClassB(); 

     Console.WriteLine(SubClassA.Instance.GetType()); 
     Console.WriteLine(SubClassB.Instance.GetType()); 

     Console.Read(); 
    } 
} 

Như tôi đã hiểu, trình biên dịch sẽ tạo ra một kiểu thừa kế kiểu mới, SubClassA và SubClassB thực sự là kiểu riêng với các biến tĩnh riêng. Nhưng có vẻ như phần tĩnh của lớp không được kế thừa nhưng được tham chiếu - tôi làm gì sai?

Trả lời

10

Thừa kế trong .NET chỉ hoạt động trên cơ sở mẫu. Các phương thức tĩnh được định nghĩa ở mức loại không ở cấp độ cá thể. Đó là lý do tại sao ghi đè không hoạt động với các phương pháp/thuộc tính/sự kiện tĩnh ...

Phương pháp tĩnh chỉ được lưu giữ một lần trong bộ nhớ. Không có bảng ảo, vv được tạo ra cho chúng.

Nếu bạn gọi phương thức mẫu trong .NET, bạn luôn cung cấp cho nó phiên bản hiện tại. Điều này bị ẩn bởi thời gian chạy .NET, nhưng nó xảy ra. Mỗi phương thức instance có tham số đầu tiên là một con trỏ (tham chiếu) đến đối tượng mà phương thức đang chạy. Điều này không xảy ra với các phương thức tĩnh (vì chúng được định nghĩa ở mức loại). Trình biên dịch nên quyết định chọn phương thức để gọi như thế nào?

+0

Tôi không nhận được nó tại sao thừa kế chỉ hoạt động trên các trường hợp, nhưng tôi phải chấp nhận nó. Cảm ơn bạn đã thông tin đó. –

+0

Hành vi tương tự được thực hiện trong PHP và Delphi –

+0

@VladislavRastrusny: Tôi không biết nó như thế nào trong năm 2010. Nhưng bây giờ trong năm 2016, có 'self ::' và 'static ::' trong PHP. –

13

Chỉ có một thuộc tính tĩnh Instance và được xác định trong BaseClass, cũng là loại duy nhất có thể thay đổi (kể từ khi đặt là private).

Điều xảy ra là các lớp con của bạn SubClassASubClassB mỗi lớp gọi hàm tạo BaseClass trong các hàm tạo của riêng chúng. Hàm tạo này đặt Instance thành cá thể BaseClass được khởi tạo.

Ví dụ cuối cùng trong mã ví dụ của bạn xảy ra là một phiên bản của SubClassB; do đó, một tài khoảnInstance được đặt thành phiên bản này vào thời điểm bạn đến số gọi Console.WriteLine của mình.

Bạn có thể đảo ngược việc xây dựng các đối tượng SubClassASubClassB của mình và bạn sẽ thấy Instance được đặt thành một phiên bản SubClassA thay thế.

+0

+1 cũng giải thích lý do tại sao nó viết SubClassB hai lần –