【问题标题】:Java runtime polymorphism not working with different parameter typesJava 运行时多态性不适用于不同的参数类型
【发布时间】:2015-06-05 17:30:33
【问题描述】:

我有 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 class add(long long),但不是这个, 它显示父类添加(双双)

但是当我在父类中添加子类的 add 方法时,它是 显示正确的输出。谁能告诉我原因。

【问题讨论】:

  • 我建议每次重写方法时都使用@Override
  • @Override 是一个很好的实践和习惯,但它不适用于这种情况,因为代码实际上并没有被覆盖。

标签: java polymorphism overloading overriding


【解决方案1】:

问题是要调用的方法签名选择了at compile time。编译器只知道parent的类型是Parent,所以唯一兼容的签名是add(double, double),因为longs都可以扩展为doubles。

Child方法add(long, long)是重载,不是覆盖,所以Child继承了add(double, double)方法,并被调用。

如果您将add(long, long) 方法添加到Parent 类中,那么它将完全匹配,并且将通过add(double, double) 方法调用。

【讨论】:

    【解决方案2】:

    你不是overridingChild 类中的方法。你是overloadingParent 类继承的方法。 Runtime polymorphism 仅适用于子类中的重写方法,而不是重载形式。

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

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

    您应该始终在您认为从父类覆盖的方法上方添加@Override 注释。这有两个好处

    1. 当您查看某个方法时,您会立即知道它正在覆盖超类中的方法。
    2. 如果父类不包含具有相似签名的方法,您会立即收到编译错误。

    【讨论】:

      【解决方案3】:

      当使用超类引用时,您不能访问子类的方法。所描述的行为是预期的,因为在Parent 中没有方法add(long, long),而只有一个方法add(double, double)(因此,您不会覆盖,而是在Child 中重载add)。

      【讨论】:

        【解决方案4】:

        您在这里重载而不是覆盖。因此,当您运行针对 Parent.add(double,double) 执行的代码时,您的长参数被扩大为双精度值。

        http://docs.oracle.com/javase/specs/jls/se8/html/jls-5.html#jls-5.1.5

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2011-12-20
          • 2012-06-05
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多