Java:如果A扩展了B,而B扩展了Object,那是多重inheritance

我刚接受采访,有人问我一个问题。

Interviewer – Java是否支持多inheritance?

– 没有

Interviewer – Java中的每个类都扩展了Object类(除了Object类),如果我们在外部扩展一个类

Class A extends B{ // some code here } 

那么你可以说A类扩展了B类和Object类,这意味着它是多重inheritance。 那么你怎么能说Java不支持多inheritance?

– 实际上B类扩展了Object类,所以当你在类A中扩展类B时,类A间接地扩展了类Object。 这是多级inheritance,不是多重inheritance。

但是我的回答并没有使他满意。

我的答案是否正确? 或者我错在哪里? 内部实际发生了什么?

我的回答是正确的?

是的,主要是,当然在你描述的背景下。 这不是多重inheritance:

对象^  -  ClassA ^  -  ClassB

这就是你所说的,单层inheritance与多层次。

这是多重inheritance:inheritance两个或更多没有任何“相互”关系的基础; 那将会从不相关的行或从先前分歧的行inheritance(在Java中,因为Object始终是一个基础,它将是后者):

对象^  -  ClassA,Object ^  -  ClassB,ClassA ^  -  ClassC,ClassB ^  -  ClassC

(图片来源:http: //yuml.me在“sc”“模式)

内部实际上会发生什么?

正如你所说:有多个层面。 编译器parsing实例上的成员时:

 obj.member 

…它看起来是否obj的types(在这种情况下是一个类,说ClassB )有member ,要么是因为它提供了直接或通过inheritance。 在运行时,JVM使用对象实际拥有的member


我之所以说“主要”是因为Java有接口,而从Java 8开始,接口上有“缺省方法”。 这会让事情变得复杂一些,但是在关于ObjectClassAClassB描述中,你所描述的关于级别的回答是正确的。

在Java中,接口总是可以让一些东西与两种不同的types有一个“是”的关系:它inheritance的类types以及它实现的几种接口types中的任何一种。 没有默认方法的接口不是以实际的方式进行多重inheritance(类必须提供实现),但是它们确实使类有可能与不相关types树有多个“是”关系。 (我不是学者,学者可能会认为他们以学术的方式提供多重inheritance。)

使用Java 8,接口可以提供他们定义的方法的默认实现,甚至在实际的层面上也真的会模糊线条。 让我们更深入地看一下:

假设我们有ClassA

 class ClassA { void doSomething() { // Code here } } 

Interface1

 interface Interface1 { default void doSomethingElse() { // Requires Java 8 // Code here } } 

最后是ClassB

 class ClassB extends ClassA implements Interface1 { } 

ClassBinheritance了ClassAdoSomething的实现。 但是它Interface1获得doSomethingElse的“默认”版本。 我们没有在ClassB实现它,但是ClassB并不是抽象的:它确实有一些东西。 它从界面获取它。 我用了“gets”而不是“inherits”,但是这看起来很像inheritance默认的方法。

这基本上是多重inheritance“光”(如“淡啤酒”)。 它能够解决真正的多重inheritance中棘手的问题,比如:

  • supertypes应该是什么? (Java 8的答案: ClassA
  • 你以什么顺序运行构造函数? (Java 8的答案:单行构造函数链,接口没有构造函数。)
  • 你是否不止一次地运行你不止一次inheritance的构造函数? (Java 8的答案:你不能多次inheritance构造函数,接口没有它们。)
  • 如果您inheritance具有相同签名的多个方法,会发生什么情况? (Java 8的答案是:如果其中一个来自基类,那就是使用的;基类的实现可以覆盖多个接口的缺省方法,如果在编译时有多个具有相同签名的缺省方法,这是一个编译时错误,如果在没有重新编译类的情况下改变了接口,并且在运行时出现这种情况,那么这是一个运行时的IncompatibleClassChangeErrorexception,列出了冲突的默认方法。

你是对的

首先,Object类是每个类的超类/基类/父类,包括用户定义的类。

所以,即使我们没有明确提到它,用户定义的类默认扩展了Object类。

就像是

 class A class B extends A but compiler read it as class A extends Object class B extends A 

证实

更多的细节检查这个java文档的inheritance

我的回答是正确的?

你说绝对正确的是它是多级inheritance而不是多重inheritance。

只有层次结构的Object ,所有类不会单独扩展对象。

采访者的反击:

如果所有类都扩展了Object ,那么在A a = new A();上将调用Object构造函数多less次A a = new A();

答案只有一次,这将是层次结构的根源。

  • 多重inheritance和类对象

是的,你是对的,正如许多人指出的那样。 我只是想说,面试不仅是关于技术知识,也是关于坚持你的枪支。 一些面试官会质疑你的答案,不是因为他们想知道你是否确信自己的信念,而是要testing你能教好别人的能力,以及你如何处理权威人物。

对于第一点,如果你不能教别人,那么你就不能成为一名导师。 现在聘请可以指导初级开发人员的人是至关重要的……因为这在经济上是合理的。

对于第二点,因为他们不希望你只是因为你的老板要求你改变技术方面。 如果您的上司要求您删除数据库中的所有索引,因为它们占用太多空间,您会这样做吗? 你会试图说服你的老板吗? 怎么样?

 Does java support multiple inheritance? 

是的接口,但不是类。

类和接口可以实现许多接口,但只扩展一个类

你的回答是正确的!

 class Object //for illustration purpose { } class B { } class A extends B { } 

当你创build一个类A的对象时,就会发生构造函数链接 。 即类A的构​​造函数隐式地调用super() ,因此B类的构造函数被调用,然后隐式地调用它的超类,它是Object类。

在java中,一个类只扩展一个类,因为该类的构造函数只调用一个超类的构造函数。 因为它们没有构造函数,所以在接口的情况下这是不正确的。

另外,当创build类A的对象时,假设已经定义了类A和类B的构造函数,则首先执行类B的构造函数,然后执行类A的构造函数。

你的回答是完全正确的。 你可以从java中的Object类解释多级inheritance支持的interms

你的回答是对的,因为java不支持从类的多重inheritance。 Java支持从接口的多重inheritance,并没有任何其他的inheritance。 但是,你可以使用类的组合,但这是另一回事。

多么愚蠢的问题。

当然,Java不支持多重inheritance,接口也不会inheritance。

inheritance仅通过“扩展”发生,而不是通过“实现”。 当你定义一个类实现了几个接口的时候,你并不是说它将是这些接口的扩展,但是它会有相同的行为,并且行为(至less在Java中)并没有定义inheritance。

对于支持多inheritance的Java,它需要支持类似的东西

 public class MI extends Object, MyOtherClass 

哪个Java不能。

那么,也许我不会得到调用面试官的问题愚蠢的工作:)

你的回答是绝对正确的。

这些types的问题只是为了检查一个候选人在概念上是否强壮。

那么对这个问题的最简单和准确的答案在这里:

类可以派生自派生自类的类的类,等等,最终派生自最上面的类Object。这样的类被认为是inheritance链中的所有类的后代,到对象“。

请参考这个链接https://docs.oracle.com/javase/tutorial/java/IandI/subclasses.html