2011-08-17 40 views
2

我從Effective C#項目23獲得下面的代碼應打印一個基類派生的:MyDerivedMessage從實現的接口

namespace ConsoleApplication1 
{ 

    interface IMsg 
    { 
     void message(); 
    } 

    public class MyMessage : IMsg 
    { 
     public void message() 
     { 
      Console.WriteLine("MyMessage"); 
     } 
    } 

    public class MyDerivedMessage : MyMessage 
    { 
     public new void message() 
     { 
      Console.WriteLine("MyDerivedMessage"); 
     } 
    } 

    class Test 
    { 

     static void Main() 
     { 
      MyDerivedMessage mdm = new MyDerivedMessage(); 
      IMsg im = mdm as IMsg; 
      im.message(); 
     } 
    } 
} 

書:

public class MyDerivedClass : MyClass 
{ 
    public new void Message() 
    { 
     Console.WriteLine("MyDerivedClass"); 
    } 
} 

添加的IMSG關鍵字的改變您派生的 類的行爲,以便IMsg.Message()現在使用派生類版本:

MyDerivedClass d = new MyDerivedClass(); 
d.Message(); // prints "MyDerivedClass". 
IMsg m = d as IMsg; 
m.Message(); // prints " MyDerivedClass " 

爲什麼我仍然可以MyMessage印刷我加上「新」來MyDerivedMessage::message()後?

回答

3

你是隱藏(或遮蔽)的方法,而不是覆蓋它。這意味着當您從聲明爲該類(或更多派生類)的變量訪問派生類時,您只會調用該方法。

注意,這是在非虛方法的默認,所以加入「新」只是被更加明確。

如果不希望這種行爲,你需要做的message方法在基類的虛,並在派生類中重寫它。

又見看起來也許這本書有一些勘誤表上new Modifier

+0

呀第二部分與虛擬和覆蓋香港專業教育學院做了,但我搞不清爲什麼書上說,它將打印派生消息。 – Kobe

+0

我不熟悉的書,但只有兩個選項:1)有書中錯誤,或2)你誤解了該書的那個部分。如果您使用與本書中相同的代碼,並聲稱輸出應該不同,那麼這本書就有錯誤。 –

+0

是的,這本書有一個錯誤 - 檢查這裏有效的C#的勘誤表:http://billwagner.cloudapp.net/EffectiveCSharp它涉及您正在閱讀的部分。 –

1

的文件,但你的MyDerivedMessage類還需要實現IMSG。如果沒有發生這種情況,那麼當因爲在Interface和MyDerivedMessage之間創建的鏈而調用im.message()時,轉換爲IMsg只會將MyMessage看作具有Message()方法。

MyDerivedMessage是,一個MyMessage MyMessage是,一個IMSG MyDerivedMessage不是is-a的IMSG

public class MyDerivedMessage : MyMessage, IMsg 
{ 
    public new void message() 
    { 
     Console.WriteLine("MyDerivedMessage"); 
    } 
}