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

bgu*_*uiz 124 c# syntax abstract-class interface

我在C#中的测试代码:

namespace DSnA
{
    public abstract class Test : IComparable
    {

    }
}
Run Code Online (Sandbox Code Playgroud)

导致以下编译器错误:

error CS0535: 'DSnA.Test' does not implement interface member
'System.IComparable.CompareTo(object)'
Run Code Online (Sandbox Code Playgroud)

由于该类Test是一个抽象类,为什么编译器要求它实现接口?这个要求不应该仅仅是具体课程的必修课吗?

Joe*_*oel 131

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

interface IFoo
{
    void Bar();
}

abstract class Foo : IFoo
{
    public abstract void Bar();
}
Run Code Online (Sandbox Code Playgroud)

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

评论和支持者抱怨说这不是问题的答案,但却忽视了这一点.有人来到Stack Overflow,收到了这个编译错误,但是有一个抽象类,其中提供一个实现是一个错误,没有一个好的解决方案 - 将不得不编写引发运行时异常的实现方法,一个可怕的工作 - 在他们拥有上述信息之前.C#需要这种显式性是好还是坏都超出了Stack Overflow的范围,与问题和这个答案无关.

  • 这并没有回答为什么这甚至是必要的问题,因为这是一个抽象类,编译器应该知道如何填空.在Java中,这不是必需的,它允许几个有用的模式,例如ioc容器上的装饰器模式,例如Spring/JavaEE(当你需要装饰托管接口的特定方法时).在.NET中相同的实现必须迫使开发人员非常冗长,尤其是在大型接口上,例如nhibernate的ISession (8认同)
  • @Ben刚看到你的评论.你可能已经弄清楚了,但万一其他人需要它.查看显式接口实现:http://msdn.microsoft.com/en-us/library/ms173157.aspx (2认同)
  • @Joel @Ben我不认为显式接口可以用于抽象类.在上面的示例代码中,将`Foo`中的定义更改为`public abstract void IFoo.Bar();`并且您会得到"public"和"abstract"不是有效修饰符的投诉. (2认同)

00j*_*0jt 10

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

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


ntz*_*lis 5

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