为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

Helenr 2021-09-03 14:44:18
我知道这里已经有人问过这个问题,但我不明白“为什么”部分。让我们以下面的例子为例: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 Thirdclass Thirdclass Third  而我所期望的是(认为 super.getClass() 应该返回父类的名称):class java.lang.Objectclass Firstclass Second这表明我不明白继承在 Java 中实际上是如何工作的。请帮助我在脑海中获得正确的概念。
查看完整描述

2 回答

?
青春有我

TA贡献1784条经验 获得超8个赞

重要的是要认识到这里只有一个对象和一个引用。可能很容易将它呈现为好像超类是位于您的 Third 实例中的 Second 的单独实例,但事实并非如此;无法引用该实例,因为它不存在。

需要明确的是:并不是在 Third 中有一个隐藏的 Second 实例super所指代,在 Second 中有一个 First,在 First 中有一个 Object。相反,只有一个对象可以作为对象,第一、第二或第三。不管局部变量或引用的类型(“静态类型”),实例本身都有一个“运行时类型”,即Third。

唯一super能为您做的就是故意调用属于超类 (JLS 15.11.2) 的成员,该成员可能通过覆盖或命名隐藏。这在这里什么都不做,因为getClass()final在 Object 上声明的方法。getClass有文档说明它“返回此对象的运行时类”(docs)。不可能有不同的实现,因此您将始终像您在问题中所做的那样收到类型 Third。


更新:不像getClassequals是非final,并且可以被覆盖。Point.equals确保返回的 ClassgetClass是相等的,并且xy是相等的。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 点时给出错误结果的方法。在实际环境中,您需要小心您的类层次结构及其含义。


查看完整回答
反对 回复 2021-09-03
?
冉冉说

TA贡献1877条经验 获得超1个赞

getClass()是一种方法Object。每个子类都没有单独的一个。如果你想像那样沿着链向上,调用getSuperclass()的结果getClass()


查看完整回答
反对 回复 2021-09-03
  • 2 回答
  • 0 关注
  • 178 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信