類別實作多個介面,介面中有**同名同簽章方法**。預設隱式實作只能有一個方法主體,無法分別實作不同介面的行為。
interface IEdit { void Paint(); }
interface ICombo { void Paint(); }
// 錯誤:無法隱式實作兩個 Paint()
class MyControl : IEdit, ICombo
{
public void Paint() { } // 編譯錯誤:實作模糊
}
class MyControl : IEdit, ICombo
{
// 語法:介面名稱.方法名稱,前面不加 public
void IEdit.Paint()
{
Console.WriteLine("IEdit.Paint:繪製編輯控制項");
}
void ICombo.Paint()
{
Console.WriteLine("ICombo.Paint:繪製下拉框控制項");
}
// 不同名方法正常 public 實作
public void OtherMethod() { }
}
var ctrl = new MyControl();
// 錯誤:ctrl.Paint() 編譯錯誤,成員模糊
// 正確:轉型呼叫
((IEdit)ctrl).Paint(); // 輸出:IEdit.Paint:繪製編輯控制項
((ICombo)ctrl).Paint(); // 輸出:ICombo.Paint:繪製下拉框控制項
// 或使用 as / is 模式
if (ctrl is IEdit edit) edit.Paint();
if (ctrl is ICombo combo) combo.Paint();
| 規則 | 說明 |
|---|---|
| 同名方法必須顯式實作 | 至少其中一個需用 介面.方法 語法 |
| 顯式實作不可加存取修飾詞 | 預設為 private,只能透過介面參考存取 |
| 不同名方法建議隱式實作 | 加 public,方便直接呼叫 |
| 顯式實作成員不可被 override | 衍生類別若要覆寫,需再次顯式實作 |
| 可同時存在隱式與顯式實作 | 但同一方法不可同時兩種 |
using System;
namespace TestInterface
{
interface IFace1
{
void Print();
void Hello();
}
interface IFace2
{
void Print();
void Goodbye();
}
class FacetoFace : IFace1, IFace2
{
// 顯式實作:同名 Print
void IFace1.Print()
{
Console.WriteLine("這是 IFace1 的 Print 函數");
}
void IFace2.Print()
{
Console.WriteLine("這是 IFace2 的 Print 函數");
}
// 隱式實作:不同名方法
public void Hello()
{
Console.WriteLine("IFace1 向您說 Hello!");
}
public void Goodbye()
{
Console.WriteLine("IFace2 向您說 GoodBye");
}
}
class Program
{
static void Main()
{
var face = new FacetoFace();
// 必須轉型呼叫同名方法
((IFace1)face).Print();
((IFace2)face).Print();
// 不同名方法直接呼叫
face.Hello();
face.Goodbye();
}
}
}
這是 IFace1 的 Print 函數
這是 IFace2 的 Print 函數
IFace1 向您說 Hello!
IFace2 向您說 GoodBye
class DerivedControl : FacetoFace, IFace1
{
// 重新顯式實作以覆寫
void IFace1.Print()
{
Console.WriteLine("DerivedControl 覆寫 IFace1.Print");
// 若需呼叫基底實作:((IFace1)((FacetoFace)this)).Print();
}
}
PaintEdit/PaintCombo)void PaintAsEdit() => ((IEdit)this).Paint();