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

时间:2014-06-24 04:32:14

标签: java class oop inheritance

我刚接受采访,我被问到一个问题。

访问员 - Java是否支持多重继承?

- 否

访问者 - Java中的每个类都扩展了类Object(类Object除外),如果我们在外部扩展一个类,如

Class A extends B{
  // some code here
}

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

- 实际上B类扩展了类Object,所以当你在类A中扩展类B时,类A会间接扩展类Object。这是多级继承,而不是多重继承。

但我的回答并不能让他满意。

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

11 个答案:

答案 0 :(得分:39)

  

我的回答是对的?

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

Object ^- ClassA ^- ClassB

这就是你所说的,具有多个级别的单一继承。

这是多重继承:继承两个或更多没有任何"的基础是"彼此的关系;这将是从不相关的行继承,或从以前分歧的行继承(在Java中,因为Object始终是基础,它将是后者):

Object ^- ClassA, Object ^- ClassB, ClassA ^- ClassC, ClassB ^- ClassC

(图片来源:http://yuml.me" scruffy"模式)

  

内部实际发生了什么?

正如你所说:有多个级别。当编译器解析实例上的成员时:

obj.member

...它会查看obj的类型(在这种情况下是一个类,比如ClassB)是否有member,因为它直接提供它或者它通过继承来实现它。在运行时,JVM使用对象实际拥有的member


我说的原因"主要是"上面是Java有接口,从Java 8开始,它有"默认方法"在接口上。这会让事情变得复杂,但是关于级别的答案在您描述的访谈者对ObjectClassAClassB所说的内容中是正确的。

在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 {
}

ClassBdoSomething继承ClassA的实施。但它获得"默认"来自doSomethingElse的{​​{1}}版本。我们没有在Interface1中实现它,但ClassB并不抽象:它确实有ClassB。它从接口获取。我用了#34;得到"而不是"继承"在那里,但这看起来像很多,就像继承默认方法一样。

这基本上是多重继承"轻" (如"淡啤酒")。它完成了真正的多重继承的棘手问题,如:

  • doSomethingElse的类型应该是什么? (Java 8'答案:super
  • 你运行构造函数的顺序是什么? (Java 8的回答:单行构造函数链接,接口没有构造函数。)
  • 您是否多次运行多次继承的构造函数? (Java 8的回答:你不能多次继承构造函数,接口也不能拥有它们。)
  • 如果继承具有相同签名的多个方法会发生什么? (Java 8的答案:如果其中一个来自基类,那就是使用过的那个;基类的实现可以覆盖多个接口的默认方法。如果在编译时有多个默认方法使用来自不同接口的相同签名,那么它就是编译时错误。如果在没有重新编译类的情况下更改了接口并且在运行时出现了这种情况,那么它就是' sa运行时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班并验证结果。