carey
carey

Reputation: 3

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 ran this code, and get the result as below:

I'm B

I'm B

both a and aaa have a instance of B, so i think the result is reasonable.

however, i ran another code, like this:

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 {

}

and, i got the result

equals(Object o) is called!

true

equals(Object o) is called!

true

equals(C c) is called!

true

equals(Object o) is called!

true

i am confused that a2.equals(new C()) call the function public boolean equals(Object o)

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

anybody can help me? really thanks!

Upvotes: 0

Views: 189

Answers (2)

Gary D.Guo
Gary D.Guo

Reputation: 9

I think when it comes to overriding, the method to be called is always determined by the type of the actual object, not the type of the variable. So when you do:

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

This cast does not change the fact that what "aaa" really contains is an object B.

Upvotes: 0

Jon Skeet
Jon Skeet

Reputation: 1501163

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

Although the value of a2 at execution time is a reference to an instance of Atest, the compile-time type of a2 is just Object. Overload resolution (i.e. choosing which method signature is called) is performed at compile time using the compile-time types; it's only the implementation of that signature that is resolved at execution time.

Upvotes: 1

Related Questions