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

Java多态练习

Java多态练习

繁星点点滴滴 2021-06-14 17:24:24
有人可以解释编译器/运行时如何在示例中运行适当的方法吗?有 6 个类和一个void m(/* ... */)具有不同参数的方法。我知道编译器会分析声明的类型。输出总是来自中产阶级的“M”。public class All {}public class Most extends All {}public class Special extends Most {}public class Top {    public void m( All p )     { System.out.println("A"); }}public class Middle extends Top {    public void m( All p )     { System.out.println("M"); }    public void m( Special p ) { System.out.println("L"); }}public class Bottom extends Middle {    public void m( Most p ) { System.out.println("V"); }    public void m( Special p ) { System.out.println("X"); }}public class Main {  public static void main(String[] args) {    All all = new All();    Most most = new Most();    Special special = new Special();    Top x = new Middle();    Top y = new Bottom();    Middle z = new Bottom();    x.m( most );     // Output is M    x.m( special );  // Output is M    y.m( all );      // Output is M    y.m( special );  // Output is M    z.m( all );      // Output is M    z.m( most );     // Output is M  }}
查看完整描述

1 回答

?
蝴蝶不菲

TA贡献1810条经验 获得超4个赞

方法覆盖在运行时通过查看对象的运行时类型来解决。编译器也决定调用哪个方法,但它只能根据表达式的编译时类型来决定。

对于对 的两次调用x,它们都Top.m(All)在编译时解析为。x是编译时类型Top,因此编译器只能查找 中声明的方法Top及其超类。编译器发现唯一可用的方法是m(All). 在运行时,要调用的方法被解析为Middle.m(All)。这是因为运行时类型x实际上是Middle,所以运行时将调用覆盖m(All)Middle。为什么不叫Middle.m(Special)?编译器已经决定Top.m(All)应该调用。运行时只会检查运行时类型是否覆盖了它。编译器不知道有一个Middle.m(Special)因为x是编译时类型Top

这两个调用y是相似的。y的编译时类型仍然是Top,因此编译器将方法解析为Top.m(All)y是运行时类型Bottom。由于Bottom继承自Middle,它也覆盖Top.m(All)。实现与Middle. 因此在运行时调用被覆盖的方法。

这两个电话z有点不同,但他们Middle.m(All)最终还是决心这样做。的编译时类型zMiddle,因此两个调用都解析为Middle.m(All)。请注意,没有Middle.m(Most),因此调用z.m(most)仍将解析为Middle.m(All)。在运行时,该方法仍然解析为,Middle.m(All)因为运行时类型Bottom不会覆盖Middle.m(All)


查看完整回答
反对 回复 2021-06-23
  • 1 回答
  • 0 关注
  • 137 浏览

添加回答

举报

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