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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/995255/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 05:08:25  来源:igfitidea点击:

Why is Multiple Inheritance not allowed in Java or C#?

c#javalanguage-designmultiple-inheritance

提问by Abdulsattar Mohammed

I know that multiple inheritance is not allowed in Java and C#. Many books just say, multiple inheritance is not allowed. But it can be implemented by using interfaces. Nothing is discussed about why it is not allowed. Can anybody tell me precisely why it is not allowed?

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

采纳答案by Razzie

The short answer is: because the language designers decided not to.

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

Basically, it seemed that both the .NET and Java designers did not allow multiple inheritance because they reasoned that adding MI added too much complexityto the languages while providing too little benefit.

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

For a more fun and in-depth read, there are some articles available on the web with interviews of some of the language designers. For example, for .NET, Chris Brumme (who worked at MS on the CLR) has explained the reasons why they decided not to:

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

  1. Different languages actually have different expectations for how MI works. For example, how conflicts are resolved and whether duplicate bases are merged or redundant. Before we can implement MI in the CLR, we have to do a survey of all the languages, figure out the common concepts, and decide how to express them in a language-neutral manner. We would also have to decide whether MI belongs in the CLS and what this would mean for languages that don't want this concept (presumably VB.NET, for example). Of course, that's the business we are in as a common language runtime, but we haven't got around to doing it for MI yet.

  2. The number of places where MI is truly appropriate is actually quite small. In many cases, multiple interface inheritance can get the job done instead. In other cases, you may be able to use encapsulation and delegation. If we were to add a slightly different construct, like mixins, would that actually be more powerful?

  3. Multiple implementation inheritance injects a lot of complexity into the implementation. This complexity impacts casting, layout, dispatch, field access, serialization, identity comparisons, verifiability, reflection, generics, and probably lots of other places.

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

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

  3. 多实现继承给实现注入了很多复杂性。这种复杂性会影响转换、布局、分派、字段访问、序列化、身份比较、可验证性、反射、泛型,以及许多其他地方。

You can read the full article here.

您可以在此处阅读全文。

For Java, you can read this article:

对于 Java,您可以阅读这篇文章

The reasons for omitting multiple inheritance from the Java language mostly stem from the "simple, object oriented, and familiar" goal. As a simple language, Java's creators wanted a language that most developers could grasp without extensive training. To that end, they worked to make the language as similar to C++ as possible (familiar) without carrying over C++'s unnecessary complexity (simple).

In the designers' opinion, multiple inheritance causes more problems and confusion than it solves. So they cut multiple inheritance from the language (just as they cut operator overloading). The designers' extensive C++ experience taught them that multiple inheritance just wasn't worth the headache.

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

在设计者看来,多重继承带来的问题和混乱比它解决的要多。所以他们从语言中削减了多重继承(就像他们削减了运算符重载一样)。设计师丰富的 C++ 经验告诉他们多重继承不值得头疼。

回答by Steve

The main (although by no means the only) reason people steer away from MI is the so called "diamond problem" leading to ambiguity in your implementation. This wikipedia articlediscusses it and explains better than I could. MI can also lead to more complex code, and a lot of OO designers claim that you do't need MI, and if you do use it your model is probably wrong. I'm not sure I agree with this last point, but keeping things simple is always a good plan.

人们远离 MI 的主要(尽管绝不是唯一)原因是所谓的“钻石问题”,导致您的实施含糊不清。这篇维基百科文章对此进行了讨论,并且解释得比我好。MI 还可以导致更复杂的代码,许多 OO 设计者声称您不需要 MI,如果您确实使用它,您的模型可能是错误的。我不确定我是否同意最后一点,但保持简单总是一个好的计划。

回答by duffymo

Multiple inheritance of implementationis what is not allowed.

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

The problem is that the compiler/runtime cannot figure out what to do if you have a Cowboy and an Artist class, both with implementations for the draw() method, and then you try to create a new CowboyArtist type. What happens when you call the draw() method? Is someone lying dead in the street, or do you have a lovely watercolor?

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

I believe it's called the double diamond inheritance problem.

我相信它被称为双钻石继承问题。

回答by inazaruk

In C++ multiple inheritance was a major headache when used improperly. To avoid those popular design issues multiple interfaces "inheritance" was forced instead in modern languages (java, C#).

在 C++ 中,如果使用不当,多重继承是一个令人头疼的问题。为了避免那些流行的设计问题,在现代语言(java、C#)中强制使用多个接口“继承”。

回答by Blindy

Another reason is that single-inheritance makes casting trivial, emitting no assembler instructions (other than checking for the compatibility of the types where required). If you had multiple-inheritance, you'd need to figure out where in the child class a certain parent starts. So performance is certainly a perk (although not the only one).

另一个原因是单继承使得转换变得微不足道,不发出汇编指令(除了在需要时检查类型的兼容性)。如果您有多重继承,您需要弄清楚某个父级在子类中的哪个位置。所以性能当然是一种特权(虽然不是唯一的)。

回答by Blindy

Back in the old days ('70s) when Computer Science was more Science and less mass production the programmers had time to think about good design and good implementation and as a result the products (programms) had high quality ( eg. TCP/IP design and implementation ). Nowadays, when everybody is programming, and the managers are changing the specs before deadlines, subtle issues like the one descriped in the wikipedia link from Steve Haigh post are difficult to track; therefore, the "multiple inheritance" is limited by compiler design. If you like it, you can still use C++ .... and have all the freedom you want :)

回到过去(70 年代),当计算机科学更多是科学而大规模生产较少时,程序员有时间考虑良好的设计和良好的实施,因此产品(程序)具有高质量(例如 TCP/IP 设计)和实施)。如今,当每个人都在编程,并且管理人员在截止日期前更改规范时,难以追踪诸如 Steve Haigh 帖子的维基百科链接中描述的微妙问题;因此,“多重继承”受到编译器设计的限制。如果你喜欢它,你仍然可以使用 C++ .... 并拥有你想要的所有自由:)

回答by Rig Veda

I take the statement that "Multiple inheritance is not allowed in Java" with a pinch of salt.

我接受了“Java 中不允许多重继承”的声明,并带有少许盐。

Multiple Inheritance is defined when a "Type" inherits from more than one "Types". And interfaces are also classified as types as they have behavior. So Java does have multiple inheritance. Just that it is safer.

当一个“类型”从多个“类型”继承时,定义了多重继承。接口也被归类为类型,因为它们具有行为。所以Java确实有多重继承。只是它更安全。

回答by mfx

Multiple Inheritance is

多重继承是

  • hard to understand
  • hard to debug (for example, if you mix classes from multiple frameworks that have identically-named methods deep down, quite unexpected synergies can occur)
  • easy to mis-use
  • not really thatuseful
  • hard to implement, especially if you want it done correctly andefficiently
  • 很难明白
  • 难以调试(例如,如果您将多个框架中的类混合在一起,这些框架在深层具有相同名称的方法,则可能会出现意想不到的协同作用)
  • 容易误用
  • 不是真的有用的
  • 难以实现,特别是如果你想要做正确有效

Therefore, it can be considered a wise choice to notinclude Multiple Inheritance into the Java language.

因此,在 Java 语言中包含多重继承可以被认为是一个明智的选择。

回答by David Thornley

Because Java has a greatly different design philosophy from C++. (I'm not going to discuss C# here.)

因为 Java 与 C++ 有着截然不同的设计理念。(我不打算在这里讨论 C#。)

In designing C++, Stroustrup wanted to include useful features, regardless of how they could be misused. It's possible to screw up big-time with multiple inheritance, operator overloading, templates, and various other features, but it's also possible to do some very good things with them.

在设计 C++ 时,Stroustrup 希望包括有用的特性,不管它们如何被滥用。使用多重继承、运算符重载、模板和各种其他功能可能会搞砸大事,但也可以用它们做一些非常好的事情。

The Java design philosophy is to emphasize safety in language constructs. The result is that there are things that are a lot more awkward to do, but you can be a lot more confident that the code you're looking at means what you think it does.

Java 设计理念是强调语言结构的安全性。结果是有些事情做起来更尴尬,但你可以更有信心地相信你正在查看的代码意味着你认为它的作用。

Further, Java was to a large extent a reaction from C++ and Smalltalk, the best known OO languages. There are plenty of other OO languages (Common Lisp was actually the first one to be standardized), with different OO systems that handle MI better.

此外,Java 在很大程度上是 C++ 和 Smalltalk(最著名的面向对象语言)的反应。还有很多其他的面向对象语言(Common Lisp 实际上是第一个被标准化的),不同的面向对象系统可以更好地处理 MI。

Not to mention that it's entirely possible to do MI in Java, using interfaces, composition, and delegation. It's more explicit than in C++, and therefore is clumsier to use but will get you something you're more likely to understand at first glance.

更不用说完全有可能在 Java 中使用接口、组合和委托来进行 MI。它比在 C++ 中更明确,因此使用起来更笨拙,但会为您提供乍一看更有可能理解的东西。

There is no right answer here. There are different answers, and which one is better for a given situation depends on applications and individual preference.

这里没有正确的答案。有不同的答案,哪种更适合特定情况取决于应用程序和个人偏好。

回答by Abhay Kokate

Java has concept, i.e. polymorphism. There are 2 types of polymorphism in java. There are method overloading and method overriding. Among them, method overriding happens with super- and subclass relationship. If we are creating an object of a subclass and invoking the method of superclass, and if subclass extends more than one class, which super class method should be called?

Java有概念,即多态。java中有两种多态。有方法重载和方法覆盖。其中,方法覆盖发生在父类和子类的关系中。如果我们创建一个子类的对象并调用超类的方法,如果子类扩展了多个类,应该调用哪个超类方法?

Or , while calling superclass constructor by super(), which super class constructor will get called?

或者,在调用超类构造函数时,会调用super()哪个超类构造函数?

This decisions are impossible by current java API features. so multiple inheritance is not allowed in java.

当前的 Java API 功能无法做出此决定。所以java中不允许多重继承。