概述:C#中的接口實現可以是隱式或顯式的。隱式實現是常見的,但顯式實現提供了更多控制權,尤其適用于特定情況,如接口方法不想公開在類上的情況。顯式實現的調用需要通過接口訪問,這可以在特定需求下提供更好的靈活性和可維護性。
介紹
在 C# 中,可以隱式或顯式方式實現接口。在大多數情況下,我們使用的是隱式接口實現,即您有一個具有相同接口簽名的方法。
internal interface IMyInterface
{
void SayHello();
}
internal class ImplicitImplementation : IMyInterface
{
public void SayHello()
{
Console.WriteLine("ImplicitImplementation says hello.");
}
}
顯式接口實現是通過在接口方法前面加上接口名稱和句點來定義的。該方法只能通過指定的接口訪問。
internal class ExplicitImplementation : IMyInterface
{
void IMyInterface.SayHello()
{
Console.WriteLine("ExplicitImplementation says hello.");
}
}
請注意,該方法沒有公共訪問修飾符,因為它只能通過接口訪問。
IMyInterface v1 = new ExplicitImplementation();
v1.SayHello();
何時必須使用顯式接口實現?
在以下情況下,必須使用顯式接口實現:
類實現兩個具有相同方法簽名的接口。
internal interface IControl
{
void Paint();
}
internal interface ICanvas
{
void Paint();
}
internal class MyControl : IControl, ICanvas
{
void IControl.Paint()
{
Console.WriteLine("IControl.Paint()");
}
void ICanvas.Paint()
{
Console.WriteLine("ICanvas.Paint()");
}
}
var control = new MyControl();
((IControl)control).Paint();
((ICanvas)control).Paint();
您不想在類類型上公開接口方法。您希望用戶將類型強制轉換為接口以訪問該方法。
internal class ExplicitImplementation : IMyInterface
{
void IMyInterface.SayHello()
{
Console.WriteLine("ExplicitImplementation says hello.");
}
}
// The following two lines would cause compile error
// 'ExplicitImplementation' does not contain a definition for 'SayHello'
ExplicitImplementation v1 = new ExplicitImplementation();
v1.SayHello();
// The following lines are OK
IMyInterface v1 = new ExplicitImplementation();
v1.SayHello();
在上面的代碼中,SayHello() 方法無法通過對象實例訪問。您必須將其轉換為接口才能訪問它。
當涉及繼承時,事情會變得復雜。假設您的基類和子類都必須實現相同的接口(隱式或顯式),在不同的場景中調用哪個實現?有很多組合。我們在這里只討論兩種情況。
基類和子類都使用隱式接口實現
internal class ImplicitImplementation : IMyInterface
{
public void SayHello()
{
Console.WriteLine("ImplicitImplementation says hello.");
}
}
internal class ImplicitImplementationSubClass : ImplicitImplementation, IMyInterface
{
public void SayHello()
{
Console.WriteLine("ImplicitImplementationSubClass says hello.");
}
}
ImplicitImplementation v3 = new ImplicitImplementation();
v3.SayHello();
ImplicitImplementation v4 = new ImplicitImplementationSubClass();
v4.SayHello();
IMyInterface v5 = new ImplicitImplementationSubClass();
v5.SayHello();
// Output
ImplicitImplementation says hello. ImplicitImplementation says hello. ImplicitImplementationSubClass says hello.
這里的輸出有點有趣:第一個是顯而易見的。第二個和第三個值得解釋。
對于第二個 (v4),運行時調用基類 ImplicitImplementation 中的接口實現,因為當基類和子類都隱式實現相同的接口時,子類實現會隱藏基類實現。
對于第三個 (v5),運行時調用子類中的接口實現,因為 v5 實例是從子類構造并強制轉換為接口的。
基類和子類都使用顯式接口實現
internal class ExplicitImplementation : IMyInterface
{
void IMyInterface.SayHello()
{
Console.WriteLine("ExplicitImplementation says hello.");
}
}
internal class ExplicitImplementationSubClass : ExplicitImplementation, IMyInterface
{
void IMyInterface.SayHello()
{
Console.WriteLine("ExplicitImplementationSubClass says hello explicitly.");
}
public void SayHello()
{
Console.WriteLine("ExplicitImplementationSubClass says hello implicitly.");
}
}
IMyInterface v1 = new ExplicitImplementation();
v1.SayHello();
IMyInterface v2 = new ExplicitImplementationSubClass();
v2.SayHello();
ExplicitImplementationSubClass v2_1 = new ExplicitImplementationSubClass();
v2_1.SayHello();
/// Output
ExplicitImplementation says hello. ExplicitImplementationSubClass says hello explicitly. ExplicitImplementationSubClass says hello implicitly.
這里的輸出更清晰易懂。顯式接口實現只能通過接口訪問。根據強制轉換為接口的真實對象實例,運行時將觸發該對象實例的接口實現。
您可以隱式和顯式實現接口。運行時將調用正確的實現,具體取決于您是使用接口還是類對象來調用它。第三個輸出 (v2_1) 演示了從類對象調用時,運行時將選擇隱式接口實現。
該文章在 2024/2/21 12:11:59 編輯過