This question already has answers here:
Overloaded method selection based on the parameter's real type
                                
                                    (7个答案)
                                
                        
                                2年前关闭。
            
                    
我正在学习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而不是基于Method E在其动态类型上?

最佳答案

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

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


需要调用谁的方法(DogCorgi),并且
对于Corgi的方法,需要调用该重载。


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

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

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

07-24 20:45