Java重载和继承规则

Lug*_*aid 31 java inheritance overloading

我一直在学习,因为我参加了考试,而且我对大多数Java没有太多问题,但我偶然发现了一个我无法解释的规则.这是一段代码片段:

public class A {

    public int method(Object o) {
        return 1;
    }

    public int method(A a) {
        return 2;
    }
}

public class AX extends A {

    public int method(A a) {
        return 3;
    }

    public int method(AX ax) {
        return 4;
    }
}

public static void main(String[] args) {
    Object o = new A();
    A a1 = new A();
    A a2 = new AX();
    AX ax = new AX();

    System.out.println(a1.method(o));
    System.out.println(a2.method(a1));
    System.out.println(a2.method(o));
    System.out.println(a2.method(ax));
}
Run Code Online (Sandbox Code Playgroud)

返回:

1 3 1 3

虽然我希望它能回归:

1 3 1 4

为什么a2的类型决定了在AX中调用哪个方法?

我一直在阅读重载规则和继承,但这似乎模糊不清,以至于我无法找到确切的规则.任何帮助将不胜感激.

Per*_*ion 30

这些方法调用的行为由Java语言规范(参考部分8.4.9)规定和描述.

调用方法时(第15.12节),在编译时使用实际参数的数量(以及任何显式类型参数)和参数的编译时类型来确定将被调用的方法的签名( §15.12.2).如果要调用的方法是实例方法,则将在运行时使用动态方法查找(第15.12.4节)确定要调用的实际方法.

在您的示例中,Java编译器确定您正在调用方法的实例的编译类型上最接近的匹配项.在这种情况下:

A.method(AX)
Run Code Online (Sandbox Code Playgroud)

最接近的方法来自类型A,带有签名A.method(A).在运行时,动态分派是在A 的实际类型(它是AX的一个实例)上执行的,因此这是实际调用的方法:

AX.method(A)
Run Code Online (Sandbox Code Playgroud)