繁体   English   中英

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

[英]Java : If A extends B and B extends Object, is that multiple inheritance

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

采访者 -Java是否支持多重继承?

-不

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

Class A extends B{
  // some code here
}

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

-实际上,类B扩展了类Object,因此,当您在类A中扩展类B时,类A间接扩展了类Object。 这是多级继承,而不是多继承。

但是我的回答使他不满意。

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

我的答案是正确的吗?

是的,大多数情况下,当然也可以根据您所描述的情况。 这不是多重继承:

对象^-ClassA ^-ClassB

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

这是多重继承:从两个或多个彼此没有任何“ is”关系的碱基继承; 将从不相关的行或先前分歧的行继承而来(在Java中,由于Object始终是基础,因此它将是后者):

对象^-ClassA,对象^-ClassB,ClassA ^-ClassC,ClassB ^-ClassC

(图片来源:“://”模式下的http://yuml.me

内部实际上会发生什么?

就像您说的那样:有多个级别。 当编译器解析实例上的成员时:

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

ClassBClassA继承了doSomething的实现。 但是它Interface1获得doSomethingElse的“默认”版本。 我们没有在ClassB实现它,但是ClassB不是抽象的:它确实具有doSomethingElse 它从接口获取它。 我用这个词“被”,而不是“继承”有,但像继承的默认方法,这看起来很多

这基本上是多重继承的“轻度”(如“轻度啤酒”中一样)。 它通过真正的多重继承来解决棘手的问题,例如:

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

你是对的

首先,对象类是包括用户定义类在内的每个类的上级/基类/父类。

因此,即使我们没有明确提及,默认情况下,用户定义的类也会扩展Object类。

就像是

class A 
class B extends A

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

证明了

有关更多详细信息,请参见此Java文档以进行继承。

我的答案是正确的吗?

绝对正确地说这是多级继承,而不是多重继承。

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

反面试官:

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

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

是的,您是正确的...正如许多其他人指出的那样。 我只是想说,面试不仅涉及技术知识,还涉及坚持不懈。 一些面试官会问您问题的答案,不是因为他们想知道您是否对自己的信念有把握,而是要测试您如何教别人,以及如何处理权威人物。

首先,如果你不能教别人,那么你就不能成为导师。 如今,聘请可以指导初级开发人员的人员至关重要……因为这样做在经济上很有意义。

第二点,因为他们不希望您的老板只是要求您更改技术方面。 如果老板因为您占用太多空间而要求您从数据库中删除所有索引,您会这样做吗? 您是否会说服老板? 怎么样?

Does java support multiple inheritance?

是的,但不是接口的类。

该类和接口可以实现许多接口,但只能扩展一个类

您的回答是正确的!

class Object //for illustration purpose
{
}

class B
{
}

class A extends B
{
}

创建类A的对象时,会发生构造函数链接 即,类A的构造函数隐式调用super() ,因此,类B的构造函数被调用,然后隐式调用其超类,即Object类。

在Java中,一个类仅扩展一个类,因为该类的构造函数仅调用一个超类构造函数。 对于接口,这是不正确的,因为它们没有构造函数。

同样,当创建了类A的对象并假定您已经定义了类A和B的构造函数时,则首先执行类B的构造函数,然后再执行类A的构造函数。

您的答案是正确的,因为Java不支持从类进行多重继承。 Java支持从接口的多重继承,并且没有任何其他继承。 但是您可以使用类的组合,但这是另一回事了。

您的回答完全正确。 您可以从Java中的Object类解释多级继承支持的术语

真是愚蠢的问题。

当然,Java不支持多重继承,接口也不被继承。

继承仅通过“扩展”发生,而不通过“实现”发生。 当您定义一个类实现多个接口时,并不是说它会是这些接口的扩展,但是它具有相同的行为,并且行为(至少在Java中是这样)没有定义继承。

为了使Java支持多重继承,它需要支持类似

public class MI extends Object, MyOtherClass

哪个Java不能。

好吧,也许我不会因为打电话给面试官的问题而愚蠢:)

您的答案是绝对正确的。

提出这些类型的问题只是为了检查候选人在概念上是否强大。

这个问题最简单,最准确的答案是:

类可以派生自类,这些类派生自类,这些类派生自类,等等,最终派生自最顶层的类Object。这样的类被认为是继承链中所有类的后代。反对。

请参考此链接https://docs.oracle.com/javase/tutorial/java/IandI/subclasses.html

您给出的答案是正确的。 面试官错了:

内部流程

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不支持多重继承。

如果要验证此过程,只需为类A生成“ javadoc”并验证结果。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM