概述:C#中的接口實(shí)現(xiàn)可以是隱式或顯式的。隱式實(shí)現(xiàn)是常見的,但顯式實(shí)現(xiàn)提供了更多控制權(quán),尤其適用于特定情況,如接口方法不想公開在類上的情況。顯式實(shí)現(xiàn)的調(diào)用需要通過接口訪問,這可以在特定需求下提供更好的靈活性和可維護(hù)性。
介紹
在 C# 中,可以隱式或顯式方式實(shí)現(xiàn)接口。在大多數(shù)情況下,我們使用的是隱式接口實(shí)現(xiàn),即您有一個(gè)具有相同接口簽名的方法。
internal interface IMyInterface
{
void SayHello();
}
internal class ImplicitImplementation : IMyInterface
{
public void SayHello()
{
Console.WriteLine("ImplicitImplementation says hello.");
}
}
顯式接口實(shí)現(xiàn)是通過在接口方法前面加上接口名稱和句點(diǎn)來定義的。該方法只能通過指定的接口訪問。
internal class ExplicitImplementation : IMyInterface
{
void IMyInterface.SayHello()
{
Console.WriteLine("ExplicitImplementation says hello.");
}
}
請(qǐng)注意,該方法沒有公共訪問修飾符,因?yàn)樗荒芡ㄟ^接口訪問。
IMyInterface v1 = new ExplicitImplementation();
v1.SayHello();
何時(shí)必須使用顯式接口實(shí)現(xiàn)?
在以下情況下,必須使用顯式接口實(shí)現(xiàn):
類實(shí)現(xiàn)兩個(gè)具有相同方法簽名的接口。
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();
您不想在類類型上公開接口方法。您希望用戶將類型強(qiáng)制轉(zhuǎn)換為接口以訪問該方法。
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() 方法無法通過對(duì)象實(shí)例訪問。您必須將其轉(zhuǎn)換為接口才能訪問它。
當(dāng)涉及繼承時(shí),事情會(huì)變得復(fù)雜。假設(shè)您的基類和子類都必須實(shí)現(xiàn)相同的接口(隱式或顯式),在不同的場(chǎng)景中調(diào)用哪個(gè)實(shí)現(xiàn)?有很多組合。我們?cè)谶@里只討論兩種情況。
基類和子類都使用隱式接口實(shí)現(xiàn)
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.
這里的輸出有點(diǎn)有趣:第一個(gè)是顯而易見的。第二個(gè)和第三個(gè)值得解釋。
對(duì)于第二個(gè) (v4),運(yùn)行時(shí)調(diào)用基類 ImplicitImplementation 中的接口實(shí)現(xiàn),因?yàn)楫?dāng)基類和子類都隱式實(shí)現(xiàn)相同的接口時(shí),子類實(shí)現(xiàn)會(huì)隱藏基類實(shí)現(xiàn)。
對(duì)于第三個(gè) (v5),運(yùn)行時(shí)調(diào)用子類中的接口實(shí)現(xiàn),因?yàn)?v5 實(shí)例是從子類構(gòu)造并強(qiáng)制轉(zhuǎn)換為接口的。
基類和子類都使用顯式接口實(shí)現(xiàn)
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.
這里的輸出更清晰易懂。顯式接口實(shí)現(xiàn)只能通過接口訪問。根據(jù)強(qiáng)制轉(zhuǎn)換為接口的真實(shí)對(duì)象實(shí)例,運(yùn)行時(shí)將觸發(fā)該對(duì)象實(shí)例的接口實(shí)現(xiàn)。
您可以隱式和顯式實(shí)現(xiàn)接口。運(yùn)行時(shí)將調(diào)用正確的實(shí)現(xiàn),具體取決于您是使用接口還是類對(duì)象來調(diào)用它。第三個(gè)輸出 (v2_1) 演示了從類對(duì)象調(diào)用時(shí),運(yùn)行時(shí)將選擇隱式接口實(shí)現(xiàn)。
該文章在 2024/2/21 12:11:59 編輯過