首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Java :如果A扩展B,B扩展对象,那是多重继承吗?

Java :如果A扩展B,B扩展对象,那是多重继承吗?
EN

Stack Overflow用户
提问于 2014-06-24 04:32:14
回答 11查看 25.3K关注 0票数 37

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

面试官- Java支持多重继承吗?

Me -不

面试官- Java中的每个类都扩展类对象(类对象除外),如果我们从外部扩展一个类,比如

代码语言:javascript
运行
复制
Class A extends B{
  // some code here
}

然后你可以说A类扩展了B类和类对象,这意味着它是多重继承。那么你怎么能说Java不支持多重继承呢?

Me -实际上B类扩展了类对象,所以当你在A类中扩展B类时,A类间接地扩展了类对象。这是多层次继承,而不是多重继承。

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

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

EN

回答 11

Stack Overflow用户

回答已采纳

发布于 2014-06-24 04:38:34

我的答案是对的?

是的,主要是,当然也是在你描述的上下文中。这不是多重继承:

就像你说的,有多个层次的单一继承。

这是多重继承:从两个或多个没有任何“基础”的基继承是彼此之间的“关系”;这将是从不相关的行继承,或者从以前有分歧的行继承(在Object中,由于Object始终是一个基,则是后者):

(图像学分:http://yuml.me/在“邋遢”模式)

实际上会发生什么呢?

就像你说的:有多个层次。当编译器解析实例上的成员时:

代码语言:javascript
运行
复制
obj.member

...it会查看obj的类型(在本例中是一个类,比如ClassB)是否有member,因为它是直接提供的,还是通过继承获得的。在运行时,JVM使用对象实际拥有的member

我上面说的“大部分”是因为Java有接口,而Java 8在接口上有“默认方法”。这使事情变得有些复杂,但是你关于等级的回答是正确的,因为你描述了面试官对ObjectClassAClassB的描述。

在Java中,接口总是能够使某些东西与两种不同类型的“是一种”关系成为可能:一种是它继承的类类型,另一种是它实现的几种接口类型。没有默认方法的接口并不是实际的多重继承(类必须提供实现),但它们确实使类有来自无关类型树的多个"is“关系成为可能。(我不是学者,一个学者可能会争辩说,他们以学术的方式提供了多重继承。)

使用Java 8,接口可以提供它们定义的方法的默认实现,这实际上模糊了实际层面上的线条。让我们更深入地看一看:

假设我们有ClassA

代码语言:javascript
运行
复制
class ClassA {
    void doSomething() {
        // Code here
    }
}

Interface1

代码语言:javascript
运行
复制
interface Interface1 {
    default void doSomethingElse() { // Requires Java 8
        // Code here
    }
}

最后是ClassB

代码语言:javascript
运行
复制
class ClassB extends ClassA implements Interface1 {
}

ClassBClassA继承了doSomething的实现。但它也可以从doSomethingElse获得“默认”版本的Interface1。我们没有在ClassB中实现它,但是ClassB不是抽象的:它确实有doSomethingElse。它是从界面上得到的。我在那里使用了“get”这个词,而不是"inherits“,但是这看起来很像继承默认的方法。

这基本上是多重遗传的“轻型”(如“淡啤酒”)。它用真正的多重继承解决了更棘手的问题,比如:

  • super的类型应该是什么?(Java 8的回答:ClassA)
  • 您运行构造函数的顺序是什么?(Java 8的回答是:单谱系构造函数链,接口没有构造函数。)
  • 是否运行继承不止一次、多次继承的构造函数?(Java 8的回答是:您不能不止一次继承构造函数,接口没有它们。)
  • 如果继承具有相同签名的多个方法,会发生什么情况?(Java 8的回答是:如果其中一个来自基类,那就是使用的;基类的实现可以覆盖多个接口的默认方法。如果在编译时具有来自不同接口的相同签名的多个默认方法,则这是编译时错误。如果在未重新编译类的情况下更改了接口,并且在运行时出现了这种情况,则是一个运行时IncompatibleClassChangeError异常,列出了冲突的默认方法。)
票数 43
EN

Stack Overflow用户

发布于 2014-06-24 04:56:15

你是对的

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

因此,即使我们没有显式地提到它,用户定义的类在默认情况下也会扩展对象类。

就像

代码语言:javascript
运行
复制
class A 
class B extends A

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

证明

有关更多细节,请查看此用于继承的java文档

票数 7
EN

Stack Overflow用户

发布于 2014-06-24 04:48:59

我的答案是对的?

你完全正确地说它是多层继承,而不是多重继承。

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

面试官的对手:

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

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

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24378375

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档