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:
这就是你所说的,单层inheritance与多层次。
这是多重inheritance:inheritance两个或更多没有任何“相互”关系的基础; 那将会从不相关的行或从先前分歧的行inheritance(在Java中,因为Object
始终是一个基础,它将是后者):
(图片来源:http: //yuml.me在“sc”“模式)
内部实际上会发生什么?
正如你所说:有多个层面。 编译器parsing实例上的成员时:
obj.member
…它看起来是否obj
的types(在这种情况下是一个类,说ClassB
)有member
,要么是因为它提供了直接或通过inheritance。 在运行时,JVM使用对象实际拥有的member
。
我之所以说“主要”是因为Java有接口,而从Java 8开始,接口上有“缺省方法”。 这会让事情变得复杂一些,但是在关于Object
, ClassA
和ClassB
描述中,你所描述的关于级别的回答是正确的。
在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 { }
ClassB
inheritance了ClassA
的doSomething
的实现。 但是它也从Interface1
获得doSomethingElse
的“默认”版本。 我们没有在ClassB
实现它,但是ClassB
并不是抽象的:它确实有一些东西。 它从界面获取它。 我用了“gets”而不是“inherits”,但是这看起来很像inheritance默认的方法。
这基本上是多重inheritance“光”(如“淡啤酒”)。 它能够解决真正的多重inheritance中棘手的问题,比如:
-
super
types应该是什么? (Java 8的答案:ClassA
) - 你以什么顺序运行构造函数? (Java 8的答案:单行构造函数链,接口没有构造函数。)
- 你是否不止一次地运行你不止一次inheritance的构造函数? (Java 8的答案:你不能多次inheritance构造函数,接口没有它们。)
- 如果您inheritance具有相同签名的多个方法,会发生什么情况? (Java 8的答案是:如果其中一个来自基类,那就是使用的;基类的实现可以覆盖多个接口的缺省方法,如果在编译时有多个具有相同签名的缺省方法,这是一个编译时错误,如果在没有重新编译类的情况下改变了接口,并且在运行时出现这种情况,那么这是一个运行时的
IncompatibleClassChangeError
exception,列出了冲突的默认方法。
你是对的
首先,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