我刚接受采访,我被问到一个问题。
访问员 - Java是否支持多重继承?
我 - 否
访问者 - Java中的每个类都扩展了类Object(类Object除外),如果我们在外部扩展一个类,如
Class A extends B{
// some code here
}
然后你可以说A类扩展了B类和Object类,这意味着它是多重继承。那你怎么说Java不支持多重继承?
我 - 实际上B类扩展了类Object,所以当你在类A中扩展类B时,类A会间接扩展类Object。这是多级继承,而不是多重继承。
但我的回答并不能让他满意。
我的回答是否正确?或者我错在哪里? 内部实际发生了什么?
答案 0 :(得分:39)
我的回答是对的?
是的,主要是,当然在您描述的上下文中。这不是多重继承:
这就是你所说的,具有多个级别的单一继承。
这是多重继承:继承两个或更多没有任何"的基础是"彼此的关系;这将是从不相关的行继承,或从以前分歧的行继承(在Java中,因为Object
始终是基础,它将是后者):
(图片来源:http://yuml.me" scruffy"模式)
内部实际发生了什么?
正如你所说:有多个级别。当编译器解析实例上的成员时:
obj.member
...它会查看obj
的类型(在这种情况下是一个类,比如ClassB
)是否有member
,因为它直接提供它或者它通过继承来实现它。在运行时,JVM使用对象实际拥有的member
。
我说的原因"主要是"上面是Java有接口,从Java 8开始,它有"默认方法"在接口上。这会让事情变得复杂,但是关于级别的答案在您描述的访谈者对Object
,ClassA
和ClassB
所说的内容中是正确的。
在Java中,接口总是能够实现"是"与两种不同类型的关系:它继承的类类型,以及实现的几种接口类型中的任何一种。没有默认方法的接口不是以实际方式进行多重继承(类必须提供实现),但是它们确实使类有多个"是"来自无关类型树的关系。 (我不是学者,可能会有学者认为他们以学术方式提供多重继承。)
使用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
从doSomething
继承ClassA
的实施。但它也获得"默认"来自doSomethingElse
的{{1}}版本。我们没有在Interface1
中实现它,但ClassB
并不抽象:它确实有ClassB
。它从接口获取。我用了#34;得到"而不是"继承"在那里,但这看起来像很多,就像继承默认方法一样。
这基本上是多重继承"轻" (如"淡啤酒")。它完成了真正的多重继承的棘手问题,如:
doSomethingElse
的类型应该是什么? (Java 8'答案:super
)ClassA
异常,列出了冲突的默认方法。)答案 1 :(得分:7)
你是对的
首先,Object类是每个类的超级/基类/父类,包括用户定义的类。
因此,即使我们没有明确提及它,用户定义的类默认扩展Object类。
喜欢
class A
class B extends A
but compiler read it as
class A extends Object
class B extends A
证明
有关详细信息,请查看此java documentation for inheritance
答案 2 :(得分:5)
我的回答是对的?
你是绝对正确的,说它是多级继承而不是多重继承。
只有层次结构的 root 为Object
,所有类不分别扩展Object。
面试官的反击:
如果所有类都扩展Object
,那么Object
上将调用A a = new A();
的构造函数的次数
答案只有一次,那将是层次结构的根。
答案 3 :(得分:3)
是的,你是正确的......正如许多其他人所指出的那样。我只是想说,采访不仅仅是关于技术知识,也是关于坚持你的枪支。一些面试官会质疑你的答案,不是因为他们想知道你是否确定自己的信念,而是要测试你能教会他人的程度以及你如何处理权威人物。
首先,如果你不能教别人,那么你就不能成为一名导师。如今聘请能够指导初级开发人员的人是至关重要的......因为这在经济上是有意义的。
对于第二点,因为他们不希望你因为老板要求你而改变技术方面。如果你的老板要求你从数据库中删除所有索引,因为它们占用了太多空间,你会这样做吗?你会试着说服你的老板吗?怎么样?
答案 4 :(得分:2)
Does java support multiple inheritance?
是接口,但不是类。
类和接口可以实现许多接口,但只扩展一个类
答案 5 :(得分:2)
你的答案是对的!
class Object //for illustration purpose
{
}
class B
{
}
class A extends B
{
}
当您创建A类对象时,会发生构造函数链接。
即,类A的构造函数隐式调用super()
,因此调用类B的构造函数,然后隐式调用其超类,即Object类。
在java中,类只扩展一个类,因为该类的构造函数只调用一个超类构造函数。在Interfaces的情况下不是这样,因为它们没有构造函数。
当创建类A的对象时,假设您已经定义了类A和B的构造函数,那么首先执行类B的构造函数,然后执行类A的构造函数。
答案 6 :(得分:1)
你的回答是对的,因为java不支持从类中继承多个。 Java支持从接口进行多次继承,并且没有任何其他继承。但是你可以使用类的组合,但这是另一个故事。
答案 7 :(得分:1)
你的答案完全没问题。您可以根据java
中Object类的多级继承支持来解释答案 8 :(得分:1)
多么愚蠢的问题。
当然,Java不支持多重继承,并且不会继承接口。
继承只通过“extends”发生,而不是通过“implements”发生。当您定义一个类实现多个接口时,您并不是说它将是这些接口的扩展,但它将具有相同的行为,并且行为(至少在Java中)不会定义继承。
对于Java来支持多重继承,它需要支持类似
的东西public class MI extends Object, MyOtherClass
哪个Java不能。
好吧,也许我不会因为打电话给面试官的问题而得不到工作:)
答案 9 :(得分:0)
你的答案绝对正确。
这些类型的问题只是为了检查候选人在概念上是否强大。
这个问题的最简单和准确的答案就在这里:
“类可以从派生自类的类派生的类派生出来,依此类推,最终派生自最顶层的类Object。这样的类被认为是所有类的后代在继承链中延伸回Object。“
请参阅此链接 https://docs.oracle.com/javase/tutorial/java/IandI/subclasses.html
答案 10 :(得分:0)
你给出的答案是正确的。面试官错了:
if suppose Class A Doesn't extends any other class
then ---> Class B extends java.lang.Object
then ---> Class A extends B
then class A also inherited the property of java 'Object' class...
所以,Java并不支持多重继承。
如果您想验证此过程,只需生成' javadoc'为你的A班并验证结果。