为什么 Java 或 C# 中不允许多重继承?

我知道在Java和C#中不允许多重继承。很多书只是说,多重继承是不允许的。但它可以通过使用接口来实现。没有讨论为什么不允许这样做。谁能告诉我为什么这是不允许的?


答案 1

简短的回答是:因为语言设计者决定不这样做。

基本上,似乎.NET和Java设计人员都不允许多重继承,因为他们认为添加MI给语言增加了太多的复杂性,而提供的收益太少

为了更有趣和深入的阅读,网络上有一些文章,其中包含对一些语言设计师的采访。例如,对于.NET,Chris Brumme(曾在MS的CLR工作)解释了他们决定不这样做的原因:

  1. 不同的语言实际上对MI的工作方式有不同的期望。例如,如何解决冲突以及是合并还是冗余重复的基础。在CLR中实现MI之前,我们必须对所有语言进行调查,找出共同的概念,并决定如何以中性语言的方式表达它们。我们还必须确定MI是否属于CLS,以及这对不想要这个概念的语言意味着什么(例如,大概 VB.NET)。当然,这就是我们作为公共语言运行时的业务,但我们还没有为MI做这件事。

  2. MI真正合适的地方数量实际上非常少。在许多情况下,多接口继承可以完成工作。在其他情况下,您可能能够使用封装和委派。如果我们要添加一个稍微不同的结构,比如mixins,那实际上会更强大吗?

  3. 多重实现继承为实现注入了大量复杂性。这种复杂性会影响转换、布局、调度、字段访问、序列化、标识比较、可验证性、反射、泛型,可能还会影响许多其他位置。

您可以在此处阅读完整文章。

对于 Java,您可以阅读本文

从Java语言中省略多重继承的原因主要源于“简单,面向对象和熟悉”的目标。作为一门简单的语言,Java的创造者想要一种大多数开发人员无需大量培训即可掌握的语言。为此,他们努力使语言尽可能类似于C++(熟悉),而不会延续C++不必要的复杂性(简单)。

在设计师看来,多重继承造成的问题和混乱比它解决的问题更多。因此,他们从语言中切断了多重继承(就像他们削减了运算符重载一样)。设计师丰富的C++经验告诉他们,多重继承不值得头痛。


答案 2

实现的多重继承是不允许的。

问题在于,如果你有一个 Cowboy 和一个 Artist 类,两者都具有 draw() 方法的实现,然后尝试创建新的 CowboyArtist 类型,编译器/运行时无法弄清楚该怎么做。调用 draw() 方法时会发生什么情况?有人躺在街上死了,还是你有一幅可爱的水彩画?

我认为这被称为双钻石继承问题。


推荐