向上转换 java RTTI

Upcasting java RTTI

public class A {
    public static void main(String[] args) {
        B b = new B();
        A a = new B();
        a.f();
        A aaa = (A) b;
        aaa.f();
    }
    public void f() {
        System.out.println("I'm A");
    }
}
class B extends A {
    public void f() {
        System.out.println("I'm B");
    }
}

i 运行这段代码,得到如下结果:

我是B

我是B

a和aaa都有一个B的实例,所以我认为这个结果是合理的。

然而,我运行另一个代码,像这样:

public class Atest {
    public static void main(String[] args) {
        Atest a1 = new Atest();
        Object a2 = new Atest();
        System.out.println(a1.equals(a2));
        System.out.println(a2.equals(a1));
        System.out.println(a1.equals(new C()));
        System.out.println(a2.equals(new C()));
    }

    public boolean equals(Object o) {
        System.out.println("equals(Object o) is called!");
        return true;
    }
    public boolean equals(Atest a) {
        return true;
    }
    public boolean equals(C c) {
        System.out.println("equals(C c) is called!");
        return true;
    }
}
class C {

}

然后,我得到了结果

equals(Object o) is called!

true

equals(Object o) is called!

true

equals(C c) is called!

true

equals(Object o) is called!

true

我很困惑 a2.equals(new C()) 调用函数 public boolean equals(Object o)

a2 是 Atest 的实例,我认为 a2.equals(new C()) 应该调用函数 public boolean equals(C c).

有人可以帮助我吗?非常感谢!

a2 is an instance of Atest, i think a2.equals(new C()) should call the function public boolean equals(C c).

虽然a2在执行时的值是对Atest实例的引用,编译时类型a2 只是 Object。重载决议(即选择调用哪个方法签名)在编译时使用编译时类型执行;它只是在执行时解析的签名的实现。

我觉得说到重写,被调用的方法总是由实际对象的类型决定的,而不是变量的类型。所以当你这样做时:

B b = new B();
A aaa = (A) b;

此转换不会改变 "aaa" 真正包含的是对象 B 的事实。