我的答案是正确的吗?
是的,主要是,当然在你描述的上下文中。这不是多重继承:

这就是你说的,具有多个级别的单继承。
这是多重继承:从两个或多个彼此没有任何“是”关系的基继承;这将从不相关的行继承,或者从以前发散的行继承(在Java中,由于始终是一个基础,因此它将是后者):Object

(图片来源:http://yuml.me 在“邋遢”模式下)
内部到底发生了什么?
正如你所说:有多个层次。当编译器解析实例上的成员时:
obj.member
...它查看的类型(在本例中是类,例如)是否具有 ,要么是因为它直接提供它,要么是通过继承具有它。在运行时,JVM 使用对象实际具有的。obj
ClassB
member
member
我上面说“大部分”的原因是Java有接口,从Java 8开始,它在接口上有“默认方法”。这让事情变得有点复杂,但是你关于水平的答案在你描述面试官所说的、、和的上下文中是正确的。Object
ClassA
ClassB
在Java中,接口总是使某些东西与两种不同类型的“is a”关系成为可能:它继承的类类型,以及它实现的几种接口类型中的任何一种。没有默认方法的接口实际上不是多重继承(类必须提供实现),但它们确实使类有可能具有来自不相关类型树的多个“is a”关系。(我不是学者,学者可能会争辩说他们以学术方式提供了多重继承。
在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
继承自 的实现。但它也从 中获取的“默认”版本。我们没有在 中实现它,但不是抽象的:它确实具有 .它从界面获取它。我在那里使用了“gets”这个词而不是“inherits”,但这看起来很像继承默认方法。doSomething
ClassA
doSomethingElse
Interface1
ClassB
ClassB
doSomethingElse
这基本上是多重继承的“轻”(如“淡啤酒”)。它解决了真正多重继承的棘手问题,例如:
- 应该是什么类型?(Java 8的答案:
super
ClassA
)
- 您以什么顺序运行构造函数?(Java 8的答案是:单系构造函数链接,接口没有构造函数。
- 您是否运行了多次、多次继承的构造函数?(Java 8的答案是:你不能多次继承构造函数,接口没有构造函数。
- 如果继承具有相同签名的多个方法,会发生什么情况?(Java 8的答案:如果其中一个来自基类,那就是使用的基类;基类的实现可以覆盖多个接口的默认方法。如果在编译时有多个默认方法具有来自不同接口的相同签名,则这是编译时错误。如果在未重新编译类的情况下更改了接口,并且这种情况在运行时出现,则它是运行时异常,列出了冲突的默认方法。
IncompatibleClassChangeError