为什么抽象类需要从它们实现的接口定义抽象方法?

Jim*_*mmy 8 c# interface abstract

当抽象类实现接口时,还需要定义或声明方法(如前所述):

public interface MyInterface
{
  void Method();
}

public abstract class MyAbstractClass : MyInterface
{
  public abstract void Method(); // required, even though MyAbstractClass does not implement
}

public class MyClass : MyAbstractClass
{
  public override void Method()
  {
  }
}

public interface MyInterface2 : MyInterface
{
  // no need to declare Method() -- why can't abstract classes do the same for unimplemented methods?
}
Run Code Online (Sandbox Code Playgroud)

c#语言的设计原理是什么要求定义实现接口的抽象类的抽象方法?对于一个抽象类来说,定义一个它没有实现的方法似乎是完全多余的(并且更糟糕的是,对于实际实现该方法必须将该方法标记为覆盖的类).我没有理由认为抽象类的行为不像MyInterface2,它继承自MyInterface但不需要声明MyInterface的方法.

Szy*_*mon 6

在实现接口的抽象类中创建的方法不需要是抽象的.抽象类也可以包含非抽象方法,您可以在那里定义接口的完整实现.继承类不需要覆盖任何这些方法.

此外,这在MSDN中描述为抽象类:

抽象类必须为所有接口成员提供实现.

实现接口的抽象类可以将接口方法映射到抽象方法.

注意"可能"这个词,它不是"必须".

还请注意MSDN关于实现接口的内容:

当类或结构实现接口时,类或结构必须为接口定义的所有成员提供实现.

对于各种类和结构都是如此.


Ond*_*cny 6

抽象类是一个完全成熟的类型,只是它不能被实例化.因此,即使其某些方法未实施,也必须声明其完整合同.特定抽象类的用户必须能够绑定到其所有方法,无论是来自接口还是直接在抽象类中声明.接口中的方法没有(至少)在抽象类中声明(如果没有实现),则使用它们无法绑定它们.

此外,类和接口有点松散耦合.类可以声明一个方法,该方法稍后映射到由其后代实现的接口中的同一签名方法.因此,从语言设计的角度来看,再次要求在抽象类中直接实现的所有接口方法都在其中实际声明.

您可以将接口视为可分离的功能(除非使用显式实现).抽象类可以独立存在,其直接用户不需要知道它的任何接口.

这是一个设计特性,只有虚拟方法才能在没有实现的情况下离开,因为虚拟方法的技术机制需要利用抽象类的整个概念在实践中起作用.


更新:示例:

public interface IFoo { void M(); }

public abstract class Bar : IFoo
{
    public virtual abstract void M();

    public void N() { }
}

public class Baz : Bar 
{
    public override void M() { … } 
}

… 

public void Method(Bar par)
{
    par.M();
}

…

Baz x = new Baz();
Method(x);
Run Code Online (Sandbox Code Playgroud)

Method看到由变量表示的实例xBar-既不是Baz也不是IFoo.换句话说,类的用户Bar根本不关心它是实现一个,两个,十个还是没有接口.它只是访问其成员.它依赖于Bar合同,而不是IFoo合同.因此,如果Bar实现IFoo,它必须定义所有成员IFoo.