[英]Java runtime polymorphism not working with different parameter types
我有3个不同的班级,
public class Parent {
public void add(double a, double b) {
System.out.println("Parent class add(double double)");
}
public class Child extends Parent {
public void add(long a, long b) {
System.out.println("Child class add(long long)");
}
}
public class Test {
public static void main(String arr[]) {
Parent parent = new Child();
parent.add((long)System.currentTimeMillis(), (long)System.currentTimeMillis());
}
}
输出应该是Child类add(long long) ,但不是这样,它显示Parent类add(double double)
但是当我在父类中添加子类的add方法时,它显示正确的输出。 任何人都可以告诉我原因。
问题是要在编译时选择要调用的方法签名。 编译器只知道parent
类型是Parent
,因此唯一兼容的签名是add(double, double)
,因为long
s可以加宽为double
。
Child
方法add(long, long)
是一个重载,而不是重写,所以Child
继承了add(double, double)
方法,并且它被调用。
如果将add(long, long)
方法add(long, long)
到Parent
类,那么它将完全匹配,并将通过add(double, double)
方法调用它。
您没有overriding
Child
类中的方法。 您正在从Parent
类overloading
继承的方法。 Runtime polymorphism
仅适用于子类中的重写方法,而不是它的重载形式。
解释为什么会发生这种情况如下:
Child
类继承了带有两个double
参数的public
add
方法。 即使您在代码中看不到它,子类实际上也包含一个带有两个double
参数的public
add
方法。 Child
中定义一个名为add
的方法时,它接受两个long
参数,实际上是重载了带有两个double
参数的继承add
方法。 run-time polymorphism
仅适用于runtime
,因此编译器在编译时不知道Child
类重载add
方法而是采用两个long
参数。 在运行时,JVM将简单地将调用分派给继承的add
方法,该方法接受两个double
参数,因为这是Child
类重写的方法。 您应始终将@Override
注释添加到您认为从父类重写的方法上方。 这有两个好处
使用超类引用时,无法访问子类的方法。 所描述的行为是预期的,因为在Parent
没有方法add(long, long)
,但只有一个方法add(double, double)
(因此,你不要覆盖,但在Child
重载add
)。
你在超载而不是在这里压倒一切。 因此,当您运行代码时,您正在针对Parent.add(double,double)执行代码,并且您的长参数将被扩展为双精度数。
http://docs.oracle.com/javase/specs/jls/se8/html/jls-5.html#jls-5.1.5
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.