私はC++から来るC#を学んでいて、壁にぶつかりました。
抽象クラスAbstractWidget、インターフェイスIDoesCoolThings、およびRealWidgetと呼ばれるAbstractWidgetから派生したクラスがあります。
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)。メンバーが明示的に実装されている場合、クラスインスタンスを介してアクセスすることはできません。インターフェイスのインスタンスを介してのみアクセスできます。あなたの例では、インスタンスをIDoesCoolThings
にキャストしない限り、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は次の2つの場合に使用します。
宣言を次のように変更します。
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.");
}
}
その後、それは動作します。
これを読む :
あなたはこのようにそれをするべきです:
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();