C#: Abstract classes need to implement interfaces?
我在C中的测试代码:
1 2 3 4 5 6 7
| namespace DSnA
{
public abstract class Test : IComparable
{
}
} |
导致以下编译器错误:
1 2
| error CS0535: 'DSnA.Test' does not implement interface member
'System.IComparable.CompareTo(object)' |
由于类Test是一个抽象类,为什么编译器需要它来实现接口?这个要求不应该只对混凝土等级是强制性的吗?
- 哈哈。我写了一件事,然后决定改变它。对不起的。:)
- 基于对已接受答案的否决和评论,我认为否决是因为问题的措辞。OP询问"为什么是这样",这将超出stackoverflow的范围。我自己也遇到过这个问题,问题更像是"我错过了什么吗?"我真的需要提供实现吗?这不就是一个抽象类的意义吗?"答案是"不,您不必提供实现(这将违反抽象类的目的),但这里是您必须做的,以使您的情况工作。"
在C中,需要一个实现接口的类来定义该接口的所有成员。对于抽象类,只需使用abstract关键字定义这些成员:
1 2 3 4 5 6 7 8 9
| interface IFoo
{
void Bar();
}
abstract class Foo : IFoo
{
public abstract void Bar();
} |
或者换一种说法:您不必"实现"它(这对抽象类来说是一个可怕的限制);但是,在C中,您必须告诉编译器您是故意将责任传递给具体的子类的——上面的代码行显示了如何做到这一点。
抱怨这不是问题的答案的评论和否决缺少要点。有些人在堆栈溢出时,收到了这个编译器错误,但有一个抽象类,在该类中提供一个实现可能是一个错误,如果没有一个好的解决方案,他们将不得不编写抛出运行时异常的实现方法,这是一项可怕的工作,直到他们得到上述信息为止。C要求这种明确性是好是坏,这超出了堆栈溢出的范围,与问题或这个答案无关。
- 我正在寻找类似的答案,但是在我的例子中,我有两个接口(例如ifoo1和ifoo2)具有相同的方法名,并且在我的基础(抽象)类中将它们标记为抽象时遇到了一些问题。你能帮忙吗?
- 不解释抽象继承器不需要实现基的抽象成员的原因。
- @本刚看到你的评论。你可能已经知道了,但万一别人需要它。查看显式接口实现:msdn.microsoft.com/en-us/library/ms173157.aspx
- @joel@ben我认为显式接口不能与抽象类一起工作。在上面的示例代码中,将Foo中的定义更改为public abstract void IFoo.Bar();,您会收到"public"和"abstract"不是有效修饰符的投诉。
- 这不回答为什么这甚至是必要的问题,考虑到这是一个抽象类,编译器应该知道如何填充空白。在Java中,这是不必要的,它允许在IOC容器(例如Spring/JavaEE)上(当需要装饰托管接口的特定方法时)的几个有用的模式,例如装饰器模式。.net中的相同实现必须迫使开发人员非常冗长,尤其是在大型接口上,如nhibernate的isession。
- Aspectj的mixins是另一个例子。它允许您将许多抽象类的部分实现混合到单个接口中。每个抽象类只需要实现它想要实现的方法。如果我要在.NET中重新创建相同的功能,那么就没有一个愚蠢的抽象方法样板妨碍我的工作。
- @是的,但是,imho,你误解了提问者需要什么,以及这实际上是一个"答案"。我也有同样的问题——因为需要提供一个实现是没有意义的,所以我被卡住了。答案是:您不必"实现"它——但是这里是您必须做的事情来告诉编译器您不需要实现它。(你[正确地]说这不是一个答案的问题,不会是一个合适的stackoverflow问题-它只是作为一个非目的而结束。)
与Java不同,C语言中:"抽象类必须提供类的基类列表中列出的接口的所有成员的实现。但是,允许抽象类将接口方法映射到抽象方法上。"
https://msdn.microsoft.com/en-us/library/aa664595(v=vs.71).aspx
- 非常清楚的答案,并且很好地提供了这两种情况,因为有时您可能还希望在基类中实现行为。
- 这里出现的一个问题是:为什么这些C样板声明(显然它们是)需要存在于抽象类中,而抽象类可能是简洁和简短的(从而使类变得混乱)?在我的C项目中,我有很多抽象类和接口——我大部分时间都在复制和粘贴Visual Studio中的方法声明。
它们不必实际实现接口。
接口方法/属性也可以是抽象的,甚至是虚拟的。因此,真正实现它们取决于子类。