【问题标题】:Java : If A extends B and B extends Object, is that multiple inheritanceJava:如果A扩展B和B扩展Object,就是多重继承
【发布时间】:2014-08-14 05:28:40
【问题描述】:

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

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

- 不

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

Class A extends B{
  // some code here
}

那么可以说A类继承了B类和Object类,也就是多继承。那怎么能说Java不支持多重继承呢?

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

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

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

【问题讨论】:

  • 你是对的。
  • 你的回答很好。面试官要么只是测试你对自己的立场有多大把握,要么自己不了解多重继承。
  • 猜猜它是你很幸运被拒绝的地方之一 :-)
  • 鉴于您解释了他的场景中发生了什么,他要么不确定继承是如何自己工作的,要么正在寻找更多的东西。根据我的经验,这种类型的问题旨在促使候选人说出“界面”这个词,尽管我当然不知道你的面试官可能真正想要什么。
  • 不,您的答案不正确,您需要说'感谢您抽出时间,先生!'

标签: java class oop inheritance


【解决方案1】:

我的答案正确吗?

是的,大多数情况下,当然在您描述的上下文中。这不是多重继承:

就是你说的,多级单继承。

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

(图片来源:http://yuml.me 处于“邋遢”模式)

内部实际发生了什么?

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

obj.member

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


我在上面说“大部分”的原因是 Java 具有接口,并且从 Java 8 开始,它在接口上具有“默认方法”。这使事情有点复杂化,但在你描述面试官对ObjectClassAClassB 的描述的背景下,你对级别的回答是正确的。

在 Java 中,接口总是使某些东西与两种不同类型具有“是一种”关系成为可能:它继承自的类类型,以及它实现的几种接口类型中的任何一种.没有默认方法的接口实际上不是多重继承(类必须提供实现),但它们确实使一个类可以从不相关的类型树中拥有多个“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 {
}

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

这基本上是多重继承的“light”(如“light beer”)。它解决了真正多重继承的棘手问题,例如:

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

【讨论】:

  • 与不含酒精的啤酒一样。
  • 哇,多么棒的解释。但我只能 +1 :( 有什么办法可以给 +1000 ;)
  • 这些照片很漂亮。我不知道为什么。
  • @user3580294:yuml.me 处于“邋遢”模式。我也不知道为什么,但我完全同意。
  • Aaaaa 并添加到书签。我会利用它。谢谢!
【解决方案2】:

你说得对

首先,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

【讨论】:

    【解决方案3】:

    我的答案正确吗?

    完全正确说它是多级继承而不是多级继承。

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

    对面试官的反击:

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

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

    【讨论】:

      【解决方案4】:

      是的,你是对的......正如许多其他人所指出的那样。我只想说,面试不仅是关于技术知识,也是关于坚持你的枪。一些面试官会质疑你的回答,不是因为他们想知道你是否确信自己的信念,而是为了测试你能教别人多少,以及你如何处理权威人物。

      第一点,如果你不能教别人,那么你就不能成为导师。如今,聘请可以指导初级开发人员的人至关重要......因为这在经济上是有意义的。

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

      【讨论】:

        【解决方案5】:
        Does java support multiple inheritance?
        

        接口可以,但类不行。

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

        【讨论】:

          【解决方案6】:

          你的答案是正确的!

          class Object //for illustration purpose
          {
          }
          
          class B
          {
          }
          
          class A extends B
          {
          }
          

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

          在java中,一个类只能扩展一个类,因为该类的构造函数只调用一个超类构造函数。这在接口的情况下是不正确的,因为它们没有构造函数。

          同样当A类的对象被创建时,假设你已经定义了A类和B类的构造函数,那么首先执行B类的构造函数,然后执行A类的构造函数。

          【讨论】:

            【解决方案7】:

            你的回答完全没问题。您可以解释 java 中 Object 类的多级继承支持

            【讨论】:

              【解决方案8】:

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

              【讨论】:

              • 你在这里有点矛盾。您说“java 不支持多重继承”,但在下一句中您说“Java 支持从接口进行多重继承”,鉴于您的第一句话,这没有意义。可能想在第一句话中添加更多细节,这样您就不会出现逻辑矛盾。
              • @user3580294 值得注意的是,我经常听到这种措辞。不过,我同意你的看法,这只是令人困惑,使情况更难以理解。
              • 您可以实现多个接口。您只能延长一门课程。
              • @jpmc26 措辞模棱两可。我猜人们会认为“类”是隐含的,但是是的,这很奇怪……
              【解决方案9】:

              真是个愚蠢的问题。

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

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

              为了让 Java 支持多重继承,它需要支持类似的东西

              public class MI extends Object, MyOtherClass
              

              哪些 Java 不能。

              好吧,也许我不会因为称面试官的问题很愚蠢而得不到这份工作:)

              【讨论】:

                【解决方案10】:

                你的答案是绝对正确的。

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

                这个问题最简单准确的答案就在这里:

                "类可以从从类派生的类派生,以此类推,最终从最顶层的类 Object 派生。这样的类被称为是所有类的后代在延伸回 Object 的继承链中。"

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

                【讨论】:

                  【解决方案11】:

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

                  内部流程

                  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”并验证结果。

                  【讨论】:

                    猜你喜欢
                    • 1970-01-01
                    • 2018-10-08
                    • 2011-12-03
                    • 1970-01-01
                    • 2016-10-24
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    相关资源
                    最近更新 更多