public class WrapperClasses{
void overloadedMethod(Number N){
System.out.println("Number Class Type");
}
void overloadedMethod(Double D){
System.out.println("Double Wrapper Class Type");
}
void overloadedMethod(Long L){
System.out.println("Long Wrapper Class Type");
}
public static void main(String[] args){
int i = 21;
WrapperClasses wr = new WrapperClasses();
//wr.overloadedMethod(i);
}
}
class mine extends WrapperClasses{
void overloadedMethod(int N){
System.out.println("Integer Class Type");
}
public static void main(String[] args){
int i = 21;
WrapperClasses wr = new mine();
wr.overloadedMethod(i);
}
}
这将打印Number Class Type
。
我了解包装器类方法重载的规则:
根据规则1,应打印Integer Class Type
。我在这里想念什么?
答案 0 :(得分:10)
在语言规范级别,这是因为参数不同的方法被视为原始类型和包装原始类型的方法不被视为override-equivalent。 (一种奇特的说法是“他们只是不这样做,因为语言规范是这样说的”)。
但从逻辑上讲,至少在子类中的int
参数“覆盖”超类中的包装参数的情况下,它们也不应该。
根据Liskov的替换原理,子类中的方法必须至少接受 超类中该方法所接受的所有参数。
如果超类方法接受包装的类,则它可以接受null
。如果子类方法只允许接受int
,则它不能接受null,因此它不能被替代。
答案 1 :(得分:5)
方法重载分辨率是在编译时根据变量的编译时类型确定的,该变量包含对要为其调用方法的实例的引用。
void overloadedMethod(int N)
仅在子类mine
中定义。因此,当您在类型为基类WrapperClasses
的引用上调用方法时,只有基类的方法才可以考虑进行重载解析。
您传递给方法的int
参数与基类的3个方法都不匹配,但是在将其装箱到Integer
后,它与void overloadedMethod(Number N)
相匹配方法。
如果您将代码更改为
int i = 21;
mine wr = new mine();
wr.overloadedMethod(i);
它将执行void overloadedMethod(int N)
。
答案 2 :(得分:3)
多态性由JVM在运行时执行。为此,这两个方法必须具有相同的运行时签名。
对于协变返回类型,编译器会生成允许这种情况发生的桥接方法,但是,Java语言规范对于包装程序与基元不需要这种桥接方法。
这可能有很多原因,但是最可能的原因是向后兼容。 Java 1.0并没有做到这一点,即使十多年后添加了自动装箱功能,也不允许这样做破坏旧代码。即包装器和基元彼此过载,而不是覆盖,因此它们现在不能。