My question is, why isn’t ClassB’s method being used?
不对。使用的方法是ClassB的方法,它从ClassA继承。
我认为这里的混乱背后的主要原因是该方法实际上不会被覆盖,而是重载。虽然Integer是Number的子类型,但由于Java参数是不变的,所以方法public void method(Integer d)不会覆盖方法public void method(Number n)。所以ClassB最终有两个(重载)方法。
静态绑定用于重载方法,编译器选择具有最具体参数类型的方法。但是在这种情况下,为什么编译器会选择public void method(Number n)而不是public void method(Integer d)。这是因为您用于调用该方法的引用类型为ClassA。
ClassA a = new ClassB(); //instance is of ClassB (runtime info)
a.method(3); //but the reference of type ClassA (compiletime info)
ClassA的唯一方法是public void method(Number n),所以这就是编译器选择的方法。请记住,这里,期望的参数类型是Number,但实际的参数,传递的整数3是自动包装的类型为整数。并且它的工作原因是因为方法参数在Java中是协变的。
现在,我想很清楚为什么它打印
ClassA: 3 class java.lang.Integer