2010-03-16 25 views
5

Đây là một trong nhiều câu hỏi cơ bản hỏi trong MS cuộc phỏng vấn gần đâyPolymorphism và C#

class A { 
    public virtual void Method1(){} 

    public void Method2() { 
     Method1(); 
    } 
} 

class B:A { 
    public override void Method1() { } 
} 

class main { 
    A obk = new B(); 
    obk.Method2(); 
} 

Vì vậy mà chức năng được gọi là? Xin lỗi vì lỗi chính tả.

+22

Tại sao bạn không dùng thử? –

+0

@ Jeff: Không quan trọng; B.Method1() vẫn là hàm được gọi. – apandit

+0

tôi nghĩ rằng theo VMT (Bảng Phương pháp Vitual) phiên bản mới nhất của phương pháp ghi đè sẽ được gọi. để có thể B.Method1() – TalentTuner

Trả lời

12
B.Method1(); 

được gọi vì nó đúng cách override phương thức ảo A.Method1();

5

Trong trường hợp này B.Method1 được gọi. Điều này là do mặc dù biến được nhập là A loại thực tế của cá thể là B. CLR đa hình gửi các cuộc gọi đến Method1 dựa trên loại thực tế của cá thể, không phải là loại biến.

2

B.Method1() được gọi là do ghi đè.

3

Quy tắc là "thành viên ghi đè trong lớp có nguồn gốc xuất sắc nhất", trong trường hợp này sẽ là "B".

4

Method1 từ lớp B sẽ được gọi, như bạn có thể nhìn thấy bằng cách chạy chương trình dưới đây:

class Program 
{ 
    static void Main(string[] args) 
    { 
     var b = new B(); 
     b.Method2(); 

     Console.ReadLine(); 
    } 
} 

class A 
{ 

    public virtual void Method1() 
    { 
     Console.WriteLine("Method1 in class A"); 
    } 

    public void Method2() 
    { 
     Method1(); 
    } 
} 

class B : A 
{ 
    public override void Method1() 
    { 
     Console.WriteLine("Method1 in class B"); 
    } 
} 
1

B.Method1 được gọi là bởi vì nó được ghi đè trong định nghĩa lớp.

1

Câu hỏi có một chút thiên vị ... nhưng ...

obk.method2() được gọi. Đổi lại, nó gọi obk.Method1, trong đó, vì nó là một thể hiện của B, đã bị ghi đè bởi B.Method1. Vì vậy, B.Method1 là những gì cuối cùng được gọi.

0

Như mọi người khác đã nói, B.Method2 được gọi. Dưới đây là một vài thông tin khác để bạn hiểu những gì đang xảy ra:

((A)B).Method2(); 
B.Method2(); 

Cả hai đều gọi B.Method1() vì nó được ghi đè đúng cách. Để gọi Method1 của A, phải có một lệnh gọi base.Method1() được thực hiện từ B (thường là nhưng không phải lúc nào cũng được thực hiện trong việc thực hiện B.Method1).

Tuy nhiên, nếu B được định nghĩa theo cách này:

class B:A { 
new public void Method1() { } 

... sau đó của một Method1() sẽ được gọi vì Method1 đã không thực sự ghi đè, đó là ẩn và giấu đi bên ngoài các quy tắc của đa hình. Nói chung, đây thường là một điều xấu để làm. Không phải luôn luôn, nhưng hãy chắc chắn rằng bạn biết rất rõ những gì bạn đang làm và tại sao bạn đang làm điều đó nếu bạn đã từng làm một cái gì đó như thế này.

Mặt khác, sử dụng mới theo cách này cũng tạo ra một số câu hỏi phỏng vấn thú vị.