我有两个类(class):
public class ClassA {
public void method(Number n) {
System.out.println("ClassA: " + n + " " + n.getClass());
}
}
和:
public class ClassB extends ClassA {
public void method(Integer d) {
System.out.println("ClassB: " + d + " " + d.getClass());
}
}
但是当我运行时:
ClassA a = new ClassB();
a.method(3);
我明白了:
ClassA: 3 class java.lang.Integer
我的问题是,为什么不使用 ClassB
的方法? a
是 ClassB
的一个实例,ClassB
的 method()
有一个 Integer
参数...
最佳答案
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
最终有两个(重载)方法。
静态绑定(bind)用于重载方法,编译器选择具有最具体参数类型的方法。但是在这种情况下,为什么编译器选择 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,被自动装箱到类型 Integer
。它起作用的原因是因为 method 参数在 Java 中是协变的。
现在,我想它打印出来的原因很清楚了
ClassA: 3 class java.lang.Integer
关于java - 使用继承的重载方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12832055/