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)最终还是决心这样做。的编译时类型z是Middle,因此两个调用都解析为Middle.m(All)。请注意,没有Middle.m(Most),因此调用z.m(most)仍将解析为Middle.m(All)。在运行时,该方法仍然解析为,Middle.m(All)因为运行时类型Bottom不会覆盖Middle.m(All)。
添加回答
举报
