【问题标题】:Inherited method in multilevel hierarchy in JavaJava中多级层次结构中的继承方法
【发布时间】:2021-05-18 16:10:12
【问题描述】:

考虑 Java 中的多级继承层次结构:

public class First {public String name() { return "First"; }}

public class Second extends First {
    public void m1() {
        System.out.print(super.name() + " rules"); 
        System.out.prinln(" but " + name() + " is even better.");
   }

   public String name() { return "Second"; }}

public class Third extends Second {public String name() { return "Third"; }}

第三个类没有覆盖 m1 方法——它只是继承了它。所以如果你运行下面的代码:

Third varThird = new Third();
varThird.m1();

你得到:

First rules but Third is even better.

这似乎违反了在运行时使用对象的实际类型来确定运行该方法的哪个实现的规则。 Second 类中的方法似乎是运行的方法。如何协调 Java 继承的规则(公共方法由子类继承)与多态性的规则(在运行时,Java 使用对象的实际类型来确定实现哪个版本的方法)。子类中没有被覆盖的方法真的被“继承”了吗?

【问题讨论】:

  • 搜索从方法的子类型开始。然后 JVM 依次向上继承层次结构寻找具体的方法。编辑:如果我没记错的话,它被称为动态绑定。
  • 你对什么感到困惑?第三个中没有 m1() 方法,如果第二个中没有 m1(),您希望执行哪个方法?
  • 虚拟方法总是在整个链条中查看它们是否被覆盖。 Java 中的所有方法都是虚方法,因此name() 是虚方法。
  • 是的,它确实打印:第三个更好。所以它确实调用了由第三类实现的名称。
  • 您提供了 SCCE 和实际输出,这很好,但我看不出您在哪里说明了您期望程序输出的内容。请您补充一下,这样我们就不必猜测了?

标签: java inheritance super multi-level


【解决方案1】:

好的,我想我现在理解了这个问题。您对为什么 super 在运行时解析失败感到困惑。

原因很简单。对于虚拟方法,Java 仅使用确切的类型来确定调用哪个方法。但是构造函数不是虚拟的,所以对构造函数的调用总是在编译时确定的。

【讨论】:

    【解决方案2】:

    搜索从方法的子类型开始。然后 JVM 依次往上继承层次,找到具体的方法。

    如果我没记错的话叫做动态绑定。

    编辑 好的,您想知道为什么当 m1() 仅在 Second.您期待输出Second is even better.

    该方法是继承vom Subtyp Second,因为JVM在继承层次结构中使用此方法,因为Third没有override此方法。 在第二你指 super().name 其中 super() 指的是父级,在这种情况下是First,因此你得到First rules but

    然后您正在调用name() 方法,该方法Third 中定义,因此返回在Third 中定义的名称

    【讨论】:

      猜你喜欢
      • 2013-10-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-04
      • 2014-12-22
      相关资源
      最近更新 更多