介面支援多重繼承,帶來強大組合能力,也引入同名成員歧義挑戰。C# 採用顯式轉型消歧策略,編譯期強制解決,零執行期開銷。
interface IInt { void Add(int i); }
interface IDbl { void Add(double d); }
interface INum : IInt, IDbl {}
class C {
void Test(INum n) {
// n.Add(1); // 錯誤:int/double 皆適用
n.Add(1.0); // 正確:僅 IDbl.Add 適用
((IInt)n).Add(1); // 正確:顯式消歧
((IDbl)n).Add(1); // 正確:隱式轉型 double
}
}
interface IBase { void F(int i); }
interface ILeft : IBase { new void F(int i); } // 覆寫遮蔽
interface IRight : IBase { void G(); }
interface IDerived : ILeft, IRight {}
class A {
void Test(IDerived d) {
d.F(1); // 呼叫 ILeft.F(最近覆寫遮蔽)
((IBase)d).F(1); // 呼叫 IBase.F
((ILeft)d).F(1); // 呼叫 ILeft.F
((IRight)d).F(1); // 呼叫 IBase.F(IRight 未覆寫)
}
}
核心原則:一旦成員被覆寫,所有存取路徑均被新成員攔截,除非顯式轉型至未覆寫的介面。
interface IControl { void Paint(); }
interface IForm { void Paint(); }
interface IPage : IControl, IForm {} // 衝突!
class Page : IPage {
void IControl.Paint() { ... } // 必須顯式實現消歧
void IForm.Paint() { ... }
}
PaintControl/PaintForm)void IFace.Method())隔離衝突、隱藏內部介面((IExact)obj).Method()),勿嘗試靠隱式轉型碰運氣
interface ILogger {
void Log(string msg);
void LogError(string msg) => Log($"[ERROR] {msg}"); // 預設實現
}
預設實現為介面演進提供新路徑,但也引入新歧義規則:類別實現優先於介面預設實現,顯式轉型仍可強制呼叫介面版本。
深度理解介面存取機制,是駕馭複雜介面體系、避免執行期驚喜的關鍵。