C#:抽象类需要实现接口吗?


131

我在C#中的测试代码:

namespace DSnA
{
    public abstract class Test : IComparable
    {

    }
}

导致以下编译器错误:

error CS0535: 'DSnA.Test' does not implement interface member
'System.IComparable.CompareTo(object)'

由于该类Test是一个抽象类,为什么编译器需要它来实现接口?这项要求不是仅对具体课程是强制性的吗?


哈哈。我写了一件事,然后决定更改它。抱歉。:)
Joel

2
根据反对意见和对已接受答案的评论,我相信反对意见的产生是因为问题的措辞方式。OP询问“为什么会这样”,这超出了stackoverflow的范围。我自己遇到了这个问题,问题更像是“我错过了什么吗?我真的必须提供实现吗?这是否克服了它成为抽象类的观点?” 对此的答案是“不,您不必提供实现(这将违背抽象类的目的),但是您要做的就是使您的情况正常运行。”
ToolmakerSteve

我发现了一种情况,您必须提供一个实现。在此接口具有可选参数。如果在基类中将方法作为抽象包括在内,则没有可选参数将无法编译继承的类(这违背了可选参数的目的)。在这种情况下,我只是抛出NotImplementedException。
Paul McCarthy

忽略我之前的评论-它没有按预期工作,在此不适用最小惊讶原则。
Paul McCarthy

Answers:


141

在C#,实现接口是一类需要定义接口的所有成员。对于抽象类,只需使用abstract关键字定义这些成员:

interface IFoo
{
    void Bar();
}

abstract class Foo : IFoo
{
    public abstract void Bar();
}

或者换一种说法:你“执行”它(这将是对抽象类可怕的限制); 但是,在C#中,您必须告诉编译器您正在故意将buck传递给具体的子类-上面的代码行显示了如何执行此操作。

抱怨说这不是问题的答案的评论和不赞成评论的人没有抓住重点。进入Stack Overflow的人已经收到了此编译器错误,但是拥有一个抽象类,其中提供一个实现是一个错误,但没有一个好的解决方案就被困住了-必须编写引发运行时异常的实现方法,这是一件艰巨的工作-around-直到获得上述信息。C#要求这种明确性的好坏,不在Stack Overflow的范围之内,与问题或答案无关。


2
@Ben刚看到您的评论。您可能已经知道了,但是万一其他人需要它。查看明确的接口实现:msdn.microsoft.com/en-us/library/ms173157.aspx
Joel

2
@Joel @Ben我认为显式接口不能与抽象类一起使用。在上面的示例代码中,将定义更改为Foopublic abstract void IFoo.Bar();然后您会抱怨“ public”和“ abstract”不是有效的修饰符。
达伦·库克

8
考虑到这是一个抽象类,并且编译器应该知道如何填充空白,所以这根本没有回答为什么甚至根本没有必要这样做的问题。在Java中,这不是必需的,它允许使用几种有用的模式,例如ioc容器上的装饰器模式,例如Spring / JavaEE(当您需要装饰托管接口的特定方法时)。.net中的同一实现将不得不迫使开发人员非常冗长,尤其是在大型接口(例如nhibernate的ISession
-Sheepy'1

1
AspectJ的mixins是另一个示例。它允许您将来自许多抽象类的部分实现混入单个接口。每个抽象类仅需要实现它想实现的方法。如果我要在.net中重新创建相同的功能,
则不会有

1
@Sheepy-是的,但是,恕我直言,您误解请求者的需求,以及这的确是一个“答案”。我同样也有同样的问题-因为提供一个实现并没有必要,所以我陷入了困境。答案是:您不必实现 ”它-但这是您必须要做的,以告诉编译器您不会实现它。(您[正确地]说这不是一个答案,也不是一个适当的stackoverflow问题-它只是作为
无用

10

与Java不同,在C#中:“抽象类必须提供该类的基类列表中列出的接口的所有成员的实现。但是,允许抽象类将接口方法映射到抽象方法上。”

https://msdn.microsoft.com/zh-CN/library/Aa664595(v=VS.71).aspx


1
超级清晰的答案,很好,您可以同时提供两种情况,因为有时您可能还想在基类中实现该行为
VinKel

这里出现的一个问题是:为什么这些C#样板声明(显然是它们)必须存在于抽象类中,否则它们可能会更简洁,更短(从而弄乱了这些类)?在我的C#项目中,我有很多抽象类和接口-大部分时间我都是在Visual Studio中复制和粘贴方法声明。
forsberg

5

他们不必实际实现接口
接口方法/属性可以是抽象的,也可以是虚拟的。因此,取决于子类来实际实现它们。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.