Java 虚函数调用

Java virtual function calls

根据我的理解,Java 中的所有函数调用都是虚拟的,数字文字的类型为 int。但为什么下面示例中的输出不同?

public class A {
    public int f(long d) {
        return 2;
    }
}
public class B extends A {
    public int f(int d) {
        return 1;
    }
}
public class M {
    public static void main(String[] args) {
        B b = new B();
        A ab = b;
        System.out.println(b.f(1));
        System.out.println(ab.f(1));
    }
}

你没有覆盖任何东西。

  • 第一次调用System.out.println(b.f(1));returns1,因为和class B一起工作,连方法名一样,只是参数不同(longint 不同)。

  • 如果参数相同 (int d),结果将是 1,因为它覆盖了 (@Override) 来自 [=18= 的方法].

  • 现在,你知道为什么第二次调用了System.out.println(ab.f(1));returns2。从class的叫法来看

实际上subclass B继承了方法f(with a long)并且添加(重载)了另一个方法f(with a int)。 当您以这种方式写下诸如 1 的值时,编译器甚至在将其分配给类型化引用之前都会将其解析为 int。更多信息:Java's L number (long) specification .

当您使用引用 ab(即 A class)调用方法 f 时,它(引用)说我只能将您发送到方法 f(具有 long),然后隐式转换将 int 1 键入 long。

让我们尝试将 A class 中方法的类型更改为 f(short), 然后 System.out.println(ab.f(1));会给你这个错误: “类型 A 中的方法 f(short) 不适用于参数 (int)”