在 C# 中对抽象类使用接口
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/684260/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Using interfaces on abstract classes in C#
提问by JubJub
I'm learning C# coming from C++ and have run into a wall.
我正在学习来自 C++ 的 C#,但遇到了一堵墙。
I have an abstract class AbstractWidget, an interface IDoesCoolThings, and a class which derives from AbstractWidget called RealWidget:
我有一个抽象类 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
{
}
When I instantiate a RealWidget object and call DoCool() on it, the compiler gives me an error saying
当我实例化一个 RealWidget 对象并在它上面调用 DoCool() 时,编译器给我一个错误说
'RealWidget' does not contain a definition for 'DoCool'
“RealWidget”不包含“DoCool”的定义
I can cast RealWidget object to an IDoesCoolThings and then the call will work, but that seems unnecessary and I also lose polymorphism (AbstractWidget.DoCool() will always be called even if i define RealWidget.DoCool()).
我可以将 RealWidget 对象转换为 IDoesCoolThings,然后调用将起作用,但这似乎没有必要,而且我也失去了多态性(即使我定义了 RealWidget.DoCool(),也将始终调用 AbstractWidget.DoCool())。
I imagine the solution is simple, but I've tried a variety of things and for the life of me can't figure this one out.
我想解决方案很简单,但我已经尝试了各种各样的事情,而且我一生都无法弄清楚这一点。
采纳答案by John Feminella
You're running into the issue because you used explicit interface implementation(EII). When a member is explicitly implemented, it can't be accessed through a class instance -- only through an instance of the interface. In your example, that's why you can't call DoCool()
unless you cast your instance to IDoesCoolThings
.
您遇到了这个问题,因为您使用了显式接口实现(EII)。当一个成员被显式实现时,它不能通过类实例访问——只能通过接口的实例。在您的示例中,这就是为什么DoCool()
除非您将实例转换为IDoesCoolThings
.
The solution is to make DoCool()
public and remove the explicit interface implementation:
解决方案是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!
In general, you use EII in two cases:
通常,您在两种情况下使用 EII:
- You have a class that must implement two interfaces, each of which contains a member that has an identical name/signature to another member in the other interface.
- You want to forceclients not to depend on the implementation details of your class, but rather on the interface that's being implemented by your class. (This is considered a good practice by some.)
- 您有一个必须实现两个接口的类,每个接口都包含一个成员,该成员与另一个接口中的另一个成员具有相同的名称/签名。
- 您希望强制客户端不依赖于您的类的实现细节,而是依赖于您的类正在实现的接口。(这被一些人认为是一种很好的做法。)
回答by Mitch Wheat
Change your declaration to:
将您的声明更改为:
public abstract class AbstractWidget : IDoesCoolThings
{
public void DoCool()
{
Console.Write("I did something cool.");
}
}
回答by J.W.
The way you implement the interface is explicit implement void IDoesCoolThings.DoCool(), if you choose implicit implement interface.
如果选择隐式实现接口,则实现接口的方式是显式实现 void IDoesCoolThings.DoCool()。
public abstract class AbstractWidget : IDoesCoolThings
{
public void DoCool()
{
Console.Write("I did something cool.");
}
}
Then it will work.
然后它会起作用。
Read this :
读这个 :
C# Interfaces. Implicit implementation versus Explicit implementation
回答by Toffee
You should do it this way:
你应该这样做:
public interface IDoesCoolThings
{
void DoCool();
}
public abstract class AbstractWidget
{
public void DoCool()
{
Console.WriteLine("I did something cool.");
}
}
public class Widget : AbstractWidget, IDoesCoolThings
{
}
Usage:
用法:
var widget = new Widget();
widget.DoCool();