繁体   English   中英

Java运行时多态性不适用于不同的参数类型

[英]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类中的方法。 您正在从Parentoverloading继承的方法。 Runtime polymorphism仅适用于子类中的重写方法,而不是它的重载形式。

解释为什么会发生这种情况如下:

  1. Child类继承了带有两个double参数的public add方法。 即使您在代码中看不到它,子类实际上也包含一个带有两个double参数的public add方法。
  2. 当您在Child中定义一个名为add的方法时,它接受两个long参数,实际上是重载了带有两个double参数的继承add方法。
  3. 由于run-time polymorphism仅适用于runtime ,因此编译器在编译时不知道Child类重载add方法而是采用两个long参数。 在运行时,JVM将简单地将调用分派给继承的add方法,该方法接受两个double参数,因为这是Child类重写的方法。

您应始终将@Override注释添加到您认为从父类重写的方法上方。 这有两个好处

  1. 当你看到一个覆盖超类方法的方法时,你马上就知道了。
  2. 如果父类不包含具有类似签名的方法,则会立即收到编译错误。

使用超类引用时,无法访问子类的方法。 所描述的行为是预期的,因为在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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM