C# 在C中使用抽象类上的接口# 我正在学习C++的C语言,并已经进入了一个墙。< /P>
我有一个抽象类AbstractWidget、一个接口IDoeSoolThings和一个从AbstractWidget派生的类RealWidget:C# 在C中使用抽象类上的接口# 我正在学习C++的C语言,并已经进入了一个墙。< /P>,c#,inheritance,interface,abstract-class,C#,Inheritance,Interface,Abstract Class,我有一个抽象类AbstractWidget、一个接口IDoeSoolThings和一个从AbstractWidget派生的类RealWidget: public interface IDoesCoolThings { void DoCool(); } public abstract class AbstractWidget : IDoesCoolThings { void IDoesCoolThings.DoCool() { Console.Write(
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对象强制转换为IDoeSoolThings,然后调用就可以了,但这似乎是不必要的,而且我还失去了多态性(AbstractWidget.DoCool()将始终被调用,即使我定义了RealWidget.DoCool()
我想解决方法很简单,但我尝试了很多方法,但我一辈子都无法解决这个问题。你遇到这个问题是因为你使用了(EII)。当一个成员被显式实现时,它不能通过类实例访问——只能通过接口的实例访问。在您的示例中,这就是为什么您不能调用
DoCool()
,除非您将实例强制转换为IDoesCoolThings
解决方案是将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.");
}
}
那就行了
请阅读以下内容:
你应该这样做:
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();
要在小部件的DoCool()中具有多态性,需要声明AbstractWidget的一个virtual.Erg。我曾在某个地方读到虚拟是接口方法的暗示。天哪,我想我已经试过了。谢谢在我的参考书中,我似乎错过了这句关键的话:“通过使用显式接口实现定义的方法不能声明为虚拟,而省略接口名称允许这种行为。”我很困惑,仅仅在抽象类中公开方法并不能解决问题,另外,我阅读的示例没有将方法定义为public或private,因此我开始相信接口方法是隐式的public和virtual。总的来说,这是一个令人尴尬的问题:)。谢谢你!如果派生类对成员的重写可能希望返回从基类实现派生的类型,则显式接口实现也可能是好的。例如,
CarFactory
和ICarFactory
可能都有MakeCar()
方法返回Car
,但FordCarFactory
可能希望有MakeCar()
方法返回FordCar
。这通常可以通过使用一个返回Car
的protected
virtualDoMakeCar
方法,并同时使用ICarFactory.MakeCar
和一个非virtualCarFactory.MakeCar
方法链来最好地处理。感谢您添加了关于隐式和显式实现的SO问题的链接!