簡體   English   中英

在C#中使用抽象類的接口

[英]Using interfaces on abstract classes in C#

我正在學習來自C ++的C#並且遇到了問題。

我有一個抽象類AbstractWidget,一個接口IDoesCoolThings,以及一個派生自AbstractWidget的類,名為RealWidget:

public interface IDoesCoolThings
{
    void DoCool();
}

public abstract class AbstractWidget : IDoesCoolThings
{
    void IDoesCoolThings.DoCool()
    {
        Console.Write("I did something cool.");
    }
}

public class RealWidget : AbstractWidget
{

}

當我實例化一個RealWidget對象並在其上調用DoCool()時,編譯器給出了一個錯誤說法

'RealWidget'不包含'DoCool'的定義

我可以將RealWidget對象轉換為IDoesCoolThings,然后調用將起作用,但這似乎是不必要的,我也失去了多態性(即使我定義了RealWidget.DoCool(),也總是會調用AbstractWidget.DoCool())。

我想解決方案很簡單,但我嘗試了各種各樣的事情,因為我的生活無法想象這一點。

您遇到了問題,因為您使用了顯式接口實現 (EII)。 當顯式實現成員時,不能通過類實例訪問它 - 只能通過接口的實例訪問它。 在您的示例中,這就是為什么除非將實例IDoesCoolThingsIDoesCoolThings否則無法調用DoCool()

解決方案是將DoCool()公開並刪除顯式接口實現:

public abstract class AbstractWidget : IDoesCoolThings
{
    public void DoCool()      // DoCool() is part of the abstract class implementation.
    {
        Console.Write("I did something cool.");
    }
}

// ...

var rw = new RealWidget();
rw.DoCool();                  // Works!

通常,您在兩種情況下使用EII:

  • 您有一個必須實現兩個接口的類,每個接口都包含一個與另一個接口中另一個成員具有相同名稱/簽名的成員。
  • 您希望強制客戶端不依賴於您的類的實現細節,而是依賴於您的類實現的接口。 (這被一些人認為是一種很好的做法。)

將您的聲明更改為:

public abstract class AbstractWidget : IDoesCoolThings 
{
    public void DoCool()
    { 
        Console.Write("I did something cool."); 
    }
}

實現接口的方式是顯式實現void IDoesCoolThings.DoCool(),如果選擇隱式實現接口。

public abstract class AbstractWidget : IDoesCoolThings
{
    public void DoCool()
    {
        Console.Write("I did something cool.");
    }
}

然后它會工作。

讀這個 :

C#接口。 隱式實現與顯式實現

你應該這樣做:

public interface IDoesCoolThings 
{
   void DoCool();
}

public abstract class AbstractWidget 
{
   public void DoCool()
   {
      Console.WriteLine("I did something cool.");
   }
}

public class Widget : AbstractWidget, IDoesCoolThings 
{
}

用法:

var widget = new Widget();
widget.DoCool();

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM