使用超类引用调用重载的继承方法

罗伯特:

我不了解这种Java行为。我有两节课:

class C1 {
    public void m1(double num) {
        System.out.println("Inside C1.m1(): " + num);
    }
}

class C2 extends C1 {
    public void m1(int num) {
        System.out.println("Inside C2.m1(): " + num);
    }
}

这是我的主要内容:

public class Main {

    public static void main(String[] args) {
        C1 c = new C2();
        c.m1(10);
    }
}

结果是:

Inside C1.m1(): 10.0

当我期望的时候:

Inside C2.m1(): 10

另外,当我尝试完成代码语法时,我发现了这一点:

在此处输入图片说明

C2类的其他m1在哪里?

我还检查了Main.class的字节码,我看到了:

Compiled from "Main.java"
public class com.company.Main {
  public com.company.Main();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V
       4: return

  public static void main(java.lang.String[]);
    Code:
       0: new           #2                  // class com/company/C2
       3: dup
       4: invokespecial #3                  // Method com/company/C2."<init>":()V
       7: astore_1
       8: aload_1
       9: ldc2_w        #4                  // double 10.0d
      12: invokevirtual #6                  // Method com/company/C1.m1:(D)V
      15: return
}

字节码告诉我它将调用C1.m1(D)V(第12行)。

为什么采用C1的方法?我试图了解这种行为。

克莱里斯-谨慎乐观-

您命名的两个方法m1没有相同的签名;超类中的一个取一个double,子类中一个的取一个int这意味着编译器将根据变量的编译时类型(C1和将调用)选择要调用的方法签名m1(double)由于该类在运行时C2没有的重写版本m1(double),因此C1将调用from的版本

规则是方法签名是在编译时根据编译时类型计算的;在运行时根据匹配的签名调度方法调用

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章