【问题标题】:Java argument with different static and dynamic types? [duplicate]具有不同静态和动态类型的 Java 参数? [复制]
【发布时间】:2018-08-26 10:27:48
【问题描述】:

我正在学习 cs61b 伯克利公开课程,对这个问题感到困惑(问题 1,第 7 行): https://sp18.datastructur.es/materials/discussion/examprep04sol.pdf

c.play(d);    // Method D is called

所以在这种情况下d 具有Dog 的静态类型和Corgi 的动态类型,在编译时记录Method D,那么为什么在运行时它仍然调用Method D 而不是@ 987654328@基于其动态类型?

【问题讨论】:

  • Java 中的“链接”是在编译时根据声明的(静态)类型完成的。
  • 虚拟方法调用仅适用于左操作数,因为方法的签名在编译时确定,在运行时不会更改。这是为了简化方法查找,尤其是您可以拥有任意数量的组合,这些组合可以匹配其他方式。

标签: java polymorphism dynamictype


【解决方案1】:

练习的目的是测试您对使用静态和动态类型进行方法分派的理解。

在您的情况下,Java 编译器必须做出两个决定:

  • 需要调用谁的方法,Dog's 或 Corgi's,并且
  • 如果是Corgi的方法,需要调用哪个重载。

第一个决定是基于调用表达式c.play(d)的左侧,即c,即Corgi。如果将Corgi 进一步子类化为CardiganPembroke,则将在运行时根据动态类型调用相应子类的方法。

编译器只关心c 的静态类型:它需要确保采用Dogplay 方法在运行时可用。虚拟调用本身由JVM根据c对象的动态类型进行。

需要调用重载的第二个决定也是在编译时完成的。这很重要,因为它在编译时“锁定”了决策。这就是为什么正确的答案是"D",即使对象d 的动态类型是Corgi

【讨论】:

  • 感谢您的快速回复!是的,我完全理解第一个决定部分,对于第二个决定,我不太明白“在编译时锁定”是什么意思,你的意思是在重载方法选择过程中只有静态类型的参数很重要吗? (相对于在重写方法选择过程中动态类型做出最终决定)
  • @SouthParker 没错,重载的决定只是基于方法参数的静态类型。
  • 干杯我也在重复的问题中找到了相同的答案。
猜你喜欢
  • 2013-02-01
  • 2011-02-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-28
  • 1970-01-01
  • 2014-02-19
  • 2016-12-15
相关资源
最近更新 更多