粗略看覺得實作介面與虛擬函式重載相同:定義物件,但物件在另一型別宣告。你被第一感覺騙了,兩者完全不同。介面定義的成員預設根本不存在實際內容。衍生類別不能重載基類中的介面成員。介面可隱式實作,即從類別公用介面隱藏。概念不同、使用也不同。
但你可以這樣實作介面:讓衍生類別修改你的實作。只需對衍生類別做一個 Hook。(譯註:寫過 C++ 知道 hook 意思,直接用原詞,像 bug 一樣。)
建立簡單介面並在類別實作:
interface IMsg { void Message(); }
public class MyClass : IMsg
{
public void Message() { Console.WriteLine("MyClass"); }
}
Message() 是 MyClass 公用介面,也可用介面指標 IMsg 存取。加入衍生類別:
public class MyDerivedClass : MyClass
{
public new void Message() { Console.WriteLine("MyDerivedClass"); }
}
注意 new 關鍵字區別前一個 Message(原則 29)。MyClass.Message() 非虛擬,衍生類別可不提供重載版本。MyDerivedClass 建立新 Message 方法,但非重載 MyClass.Message:它隱藏原方法。且 MyClass.Message 仍可透過 IMsg 參考存取:
MyDerivedClass d = new MyDerivedClass();
d.Message(); // prints "MyDerivedClass"
IMsg m = d as IMsg;
m.Message(); // prints "MyClass"
介面方法非虛擬,實作介面時必須在詳細相關型別中宣告具體實作內容。
若不存取基類,可在衍生類別重新實作介面:
public class MyDerivedClass : MyClass, IMsg
{
public new void Message() { Console.WriteLine("MyDerivedClass"); }
}