【问题标题】:Why interface cannot inherit pure abstract class为什么接口不能继承纯抽象类
【发布时间】:2014-06-01 15:43:34
【问题描述】:

众所周知,一个接口可以继承另一个接口,接口只能包含方法签名。

interface A
{
    void DoWorkA()
    { }
}

interface B : A
{
    void DoWorkB()
    { }
}

现在实现接口B的类需要提供两个函数体。

public class ABC : B
{
    public void DoWorkB()
    {
        //do some work
    }

    public void DoWorkA()
    {
        //do some work
    }
 }

那么为什么接口不能继承抽象类或者普通类呢。

所以如果接口继承了抽象类,那么实现这个接口的类需要提供抽象类的所有接口和抽象方法的实现。

为什么这是不可能的。

【问题讨论】:

  • 这个问题的目的更多是为了澄清 C# 语法还是更多的设计原理?
  • 为什么应该是可能的?说实话没有任何意义。
  • 您是否正在寻找一种方式来表达“我希望接口 X 拥有 ABC 类的所有公共成员。”?这可能是一个有用的功能,但另一方面,它也可能不经常使用,而且,由于类成员可以有不同的访问修饰符,因此需要更多的思考。
  • @O.R.Mapper 我是如何解释这个问题的,“为什么类 ABC 不能暗示接口 IABC?”我认为它可以,但没有语言结构支持它。

标签: c# .net interface abstract-class


【解决方案1】:

因为接口是语言定义的契约。它是一种用于描述合约的语言特定类型:因此您可以聚合不同的合约(从另一个接口继承一个接口),但合约本身不能扩展某些东西。

抽象类,可以包含实现:

//PERFECTLY VALID ABSTRACT CLASS DEFINITION
public abstract class A {

    public abstract void Overridable(); //ABSRTACT

    public void DoSomething() {
       //METHOD BODY
    }
}

因此,从可能并且通常具有实现的东西继承接口,从语言设计和 OPP 的角度来看是没有意义的。

【讨论】:

    【解决方案2】:

    接口和类的主要区别在于接口只提供签名而不提供实现。如果继承一个类的接口继承了它的实现,它将提供实现,不再是一个接口。

    【讨论】:

      【解决方案3】:

      理论上,您可以设计一种可以实现这一目标的语言。 C# 的设计者选择遵循 OOP 的通用约定,其中类不隐含接口,因此不能被继承。

      【讨论】:

      • 这没有意义。接口没有任何实现。根据这个定义,你不能继承一个实现......因为它不再是“无实现的”。
      • @SimonWhitehead:您仍然可以继承接口(即公共成员的声明)。可以这么说,继承一切,让一切抽象。但是,某些成员不是虚拟的事实只是此类功能必须考虑的障碍之一。
      • @O.R.Mapper ..这听起来完全没有意义,因为您可以从其他接口继承。从您的实现中提取一个实际的接口并将其放入继承链中。无论如何..我现在意识到卡尔指的是鸭子打字..我最初并没有那样读它。
      • @SimonWhitehead:如果您无法控制类ABC,则无法从其他接口继承。因此,我可以看到“提取”界面的愿望是如何有意义的,尽管有概述的困难。尝试在单一语言的限制之外思考:-)
      • @O.R.Mapper 好点……但是我在考虑问题中标记的语言的限制:P
      【解决方案4】:

      因为一个接口不允许有任何方法或构造函数在其中定义。

      从一个类继承一个接口意味着它有一些方法和至少一个构造函数。即使您没有在基类中定义构造函数,编译器仍会生成一个。该接口还需要一个构造函数来调用基本构造函数,因此您将违反上述规则。

      视情况而定,您可能会违反更多规则。如果基类有一些方法或字段,接口也会继承它。

      如果你从一个继承另一个类的接口继承一个类,接下来会发生什么?如果您在所有 .net 语言中都禁止的类中继承多个接口,则可以进行多重继承。

      【讨论】:

        【解决方案5】:
        1. 据我所知,如果你在接口中继承抽象类(实际上你不能这样做),那么抽象类中的所有抽象方法都必须被覆盖。但是你不能提供功能(定义)对于接口中的方法,这是原因之一。

        2. 不继承接口中的普通类的另一个原因是,如果您继承的任何类在某种意义上具有现有对象的属性(接口是现有类的所有成员(甚至是功能)),接口中不支持。

        3. 您不能在接口中创建构造函数或析构函数,但现有类至少包含一个构造函数(如果没有编译器将创建它)。

        4. 如果现有类继承了任何其他类,则接口继承了 c# 中不支持的两个子类(可能包含相同的方法名称)。

        您将有更多理由支持接口中的继承。

        【讨论】:

          猜你喜欢
          • 2014-10-09
          • 2017-11-27
          • 2022-11-18
          • 2013-01-09
          • 2014-09-09
          • 2011-09-18
          • 1970-01-01
          • 2021-06-25
          • 2011-11-03
          相关资源
          最近更新 更多