Java:从子类调用 super.getClass()

我知道这里已经有人问过这个问题,但我不明白“为什么”部分。


让我们以下面的例子为例:


public class First {

    First() {

       System.out.println(super.getClass());

    }

}


public class Second extends First {

    Second() {

       System.out.println(super.getClass());

    }

}


public class Third extends Second {

    Third() {

       System.out.println(super.getClass());

    }

}  

当我实例化一个类型为 Third 的对象时:


public class Main {

    public static void main(String[] args) {

        Third third = new Third();

    }

}

输出是:


class Third

class Third

class Third  

而我所期望的是(认为 super.getClass() 应该返回父类的名称):


class java.lang.Object

class First

class Second

这表明我不明白继承在 Java 中实际上是如何工作的。请帮助我在脑海中获得正确的概念。


Helenr
浏览 179回答 2
2回答

青春有我

重要的是要认识到这里只有一个对象和一个引用。可能很容易将它呈现为好像超类是位于您的 Third 实例中的 Second 的单独实例,但事实并非如此;无法引用该实例,因为它不存在。需要明确的是:并不是在 Third 中有一个隐藏的 Second 实例super所指代,在 Second 中有一个 First,在 First 中有一个 Object。相反,只有一个对象可以作为对象,第一、第二或第三。不管局部变量或引用的类型(“静态类型”),实例本身都有一个“运行时类型”,即Third。唯一super能为您做的就是故意调用属于超类 (JLS 15.11.2) 的成员,该成员可能通过覆盖或命名隐藏。这在这里什么都不做,因为getClass()是final在 Object 上声明的方法。getClass有文档说明它“返回此对象的运行时类”(docs)。不可能有不同的实现,因此您将始终像您在问题中所做的那样收到类型 Third。更新:不像getClass,equals是非final,并且可以被覆盖。Point.equals确保返回的 ClassgetClass是相等的,并且x和y是相等的。equalsPoint3D没有编写完全不同的 实现,而是遵循 Point 的定义,equals并额外检查该z字段是否相等,这是因为 Point 会检查那个object.getClass() == this.getClass(),而不是那个object.getClass() == Point.class。它不能简单地通过调用来做到这一点equals,因为那会使用Point3D.equals实现;相反,它必须调用super.equals以查看 Point 将如何计算equals。但是,我希望这是课程中的一个示例,因为多态性断言 Point3D 是一个 Point 并且可以做 Point 可以做的任何事情(请参阅Liskov 替换原则)。对于 Point 和 Point3D,这可能会产生误导:您可以编写一个double distanceBetween(Point a, Point b)使用 2D 点按预期工作但在使用 3D 点时给出错误结果的方法。在实际环境中,您需要小心您的类层次结构及其含义。

冉冉说

getClass()是一种方法Object。每个子类都没有单独的一个。如果你想像那样沿着链向上,调用getSuperclass()的结果getClass()。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java