2013-04-08 49 views
8

所有調用實例的運行時類型d因此,所有F(的)的調用應該在D.這個碼塊的輸出沒有意義的我

using System; 
class A 
{ 
    public virtual void F() { Console.WriteLine("A.F"); } 
} 
class B: A 
{ 
    public override void F() { Console.WriteLine("B.F"); } 
} 
class C: B 
{ 
    new public virtual void F() { Console.WriteLine("C.F"); } 
} 
class D: C 
{ 
    public override void F() { Console.WriteLine("D.F"); } 
} 
class Test 
{ 
    static void Main() { 
     D d = new D(); 
     A a = d; 
     B b = d; 
     C c = d; 
     a.F(); 
     b.F(); 
     c.F(); 
     d.F(); 
    } 
} 
聲明的F()方法

輸出爲:

B.F 
B.F 
D.F 
D.F 

不應該輸出爲:

D.F 
D.F 
D.F 
D.F 
+0

您應該編輯問題標題到很多問題 – MarcinJuraszek 2013-04-08 07:08:54

回答

1

您在C級使用new public virtual void F():乙。這意味着,在CF()BF()是不同的方法。

所以,當你重寫CD類,在D類中的方法F()從類C,不B覆蓋。

另一個明顯的例子可以是這樣的:

​​
+0

但是所有調用實例的運行時類型都是D,這意味着D中F()的實現就是被調用的實例。 – 2013-04-08 06:22:32

+0

直到方法'F()'被覆蓋。如果您使用'new',它將作爲新方法處理,而不是被覆蓋 – Fendy 2013-04-08 06:25:09

+0

知道了!並且因爲在運行時對調用者類型的最接近的實現,在這種情況下,對於a.F(),B中的F(); b.F();和F()in D for c.F(); d.F();被調用。 – 2013-04-08 06:35:37

7

Versioning with the Override and New Keywords (C# Programming Guide)

如果在派生類的方法的前面有新的關鍵字, 所述方法被定義爲獨立的方法在基類 類中。

所以找你從ABF方法不連接這些從CD,這就是爲什麼你會得到你所得到的。

在運行時,CLR查找virtual應該從類型出發變量使用方法的實現被宣佈爲高達鍵入它確實是。對於a.F()b.F()它停止上B.F()聲明,因爲C.F()是(因爲new)的不同方法。

1

它不應該...

A a = d; 

這意味着你正在創建一個類A類型。並且由於您明確覆蓋B類中的相關方法; A採用B類中的方法。

另一方面,在這一行;

new public virtual void F() { Console.WriteLine("C.F"); } 

你宣佈,你不會使用new關鍵字使用F()方法從基地。

如果您已經重寫了F()方法DC類,所有的實例會叫在D類中聲明的F()方法。