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)
。
添加回答
举报