【问题标题】:C# 8 - multiple inheritance "abstract class"? [duplicate]C# 8 - 多重继承“抽象类”? [复制]
【发布时间】:2019-04-30 23:35:06
【问题描述】:

在我看来,就像 C# 8.0 的特性,默认接口成员实现,本质上允许在接口级别创建实现。再加上一个类可以实现多个接口的事实,它似乎非常接近类的多重继承结构。据我了解,这似乎与语言设计的核心完全相反。

这种差异从何而来?这为实际的抽象类留下了多少空间?

This question 已被建议作为我的答案,虽然它很有用,但它并不能完全回答我的问题。更准确地说:

  • 我一直认为单继承是 C# 设计的核心原则之一,这就是为什么实现此功能的决定让我感到惊讶,并且我很想知道它源自何处(特别是 C#)。
  • 链接的问题没有回答它为抽象类留出了什么空间。

【问题讨论】:

  • @Aomine 虽然该问题确实包含有用的见解,但它只回答了我的第一个问题(即不是 C# 特定的,关于我一直认为单继承是主要原则的语言设计)并且根本没有回答我的第二个问题
  • 嗯,C# 一直允许实现多个接口。默认实现要求将对象转换为具有实现的接口,类似于当前显式接口实现的工作方式。我不确定默认方法是否会极大地改变模型。
  • @JonathonChase 多接口实现与继承多个实现不同。我绝不是说这是一个错误的设计决定。我认为它为滥用打开了空间,但好的用例可能远远超过风险。不过,我之前没有使用过支持此功能的语言,所以我很好奇它的影响——因此提出了这个问题。
  • @Lasooch 默认接口方法用于实现traits。从 Java 8 开始,它们就是 used in Java。PHP 具有特征 since 5.4。他们可以在少数情况下替换抽象类,但这不是主要用例。主要好处是没有多重继承的特征组合
  • @Lasooch check this answer 回答与 C# 中的特征相关的问题。该代码特定于该问题,因此不完全适合作为此处的答案而不进行修改。它包含一些指向 Sharplab.Io 示例的链接,尽管它们显示了编译器如何处理特征/默认接口方法

标签: c# interface abstract-class c#-8.0


【解决方案1】:

我一直认为单继承是 C# 设计的核心原则之一

这是不准确的。单继承是设计目标的一种手段,但它本身并不是一个目标。

这就像说自动变速器是汽车制造商的核心设计原则,而实际目标是让汽车更轻松、更安全。纵观汽车市场,手动变速箱仍然在市场的低端(因为它们更便宜)和高端(高性能跑车)中蓬勃发展,它们非常适合用途。这些领域的许多型号仍然可以使用任何一种传输方式。

在 C# 中导致单一继承的实际设计目标更多是关于内存访问和重载解决方案的安全性和正确性。与单继承相比,多继承很难在数学上验证这些东西。但是当他们找到优雅的解决方案时,C# 设计人员添加了许多扩展单继承界限的功能。除了接口之外,我们还有部分类、泛型(以及后来的协变/逆变)和委托成员,它们都朝着这个方向发展。

在这种情况下,默认实现在安全提供弱多重继承方面是有效的,因为继承的功能不会从两个方向向下级联继承树。你不能通过继承两个具有不同接口实现的不同类来制造冲突;您只能使用自己的类实现、默认实现或通过继承获得的单一实现。

【讨论】:

    【解决方案2】:

    请注意,默认接口实现不允许允许多重继承,至少在 C++ 存在问题的意义上是这样。 原因 多重继承是 C++ 中的一个问题,即当一个类从多个具有相同签名的方法的类继承时,对于 需要哪个 实现可能会变得模棱两可。使用默认接口实现,这种歧义是不可能的,因为类本身没有实现方法。必须将对象强制转换为接口才能调用实现的方法。因此,可以在同一个实例上调用具有相同 signature 的多个方法,但您必须明确告诉编译器 您正在执行哪个 方法。

    【讨论】:

      【解决方案3】:

      链接的post很好地回答了您的第一个问题。

      至于:

      链接的问题没有回答它为摘要留出的空间 类。

      虽然看起来和听起来很相似的接口默认方法实现当然不会取代抽象类,也不会使它们变得多余,但很大的原因是:

      接口不能定义类级别的字段/变量,而抽象类可以有状态

      还有一些其他的差异,虽然没有前面提到的那么大,您可以在各种博客/帖子中找到:

      等等

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-11-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多