在超类型对象上强制转换在java中返回类型子类的对象

AN0*_*N00 3 java binding casting subclass superclass

我已经实现了以下代码,以便了解静态和动态绑定之间的区别:

class A {

    int met(A a) {
        return 0;
    }

    int met(B b) {
        return 1;
    }

    int met(C c) {
        return 2;
    }
}

class B extends A {

    int met(A a) {
        return 3;
    }

    int met(B b) {
        return 4;
    }

    int met(C c) {
        return 5;
    }
}

class C extends B {

    int f() {
        return ((A)this).met((A)this);
    }
}

public class Test {

    public static void main(String[] args) {

        C x = new C();
        System.out.println(x.f());
    }
}
Run Code Online (Sandbox Code Playgroud)

我得到的结果是3,但我不明白为什么,因为第一次演员是为了A.

Jon*_*eet 6

那么,让我们来看看电话:

((A)this).met((A)this);
Run Code Online (Sandbox Code Playgroud)

这相当于:

A target = this;
A argument = this;
target.met(argument);
Run Code Online (Sandbox Code Playgroud)

因此,对于最后一行,编译器根据所涉及的编译时类型查找签名 - 它将查找A(和超类)一个被调用的方法,该方法met具有与之兼容的参数A(编译时类型的参数).重载决议发现答案是:

int met(A a)
Run Code Online (Sandbox Code Playgroud)

这是在编译时确定的签名.但是,该方法的实现是在执行时根据方法调用的执行时间目标确定的.这种类型在C这里 - 因为this是对实例的引用C.(该f方法在.的实例上调用C.)

现在C不覆盖int met(A a),但B(它的超类)确实 - 所以这是使用的实现.B 同样覆盖met(B b)并且met(C c)因为编译器已经确定它met(A a)是被调用的方法没关系.