MST
MST

Reputation: 131

Ambiguous java hierarchy

My question is why x.proc(z) below does print 57 instead of printing 39 ?

class X
{
    protected int v=0;
    public X() {v+=10; System.out.println("constr X");}
    public void proc(X p) {System.out.println(43);}
}

class Y extends X
{
    public Y() {v+=5;System.out.println("constr Y");}
    public void proc(X p) {System.out.println(57);}
    public int getV() {return v;}
}

class Z extends Y
{
    public Z() {v+=9;System.out.println("constr Z");}
    public void proc(Z p) {System.out.println(39);}
}

class Main
{
    public static void main(String argv[])
    {
        X x = new Z(); // v=24
        Y y = new Z(); // v=24
        Z z = new Z(); // v=24

        x.proc(z); //57
    }
}

X x refers to a Z object, and class Z does have the method proc(Z p) but it also has the method proc(X p). Also the parameter z is of type Z so it would be reasonable to print 39.

Upvotes: 1

Views: 67

Answers (3)

Antoniossss
Antoniossss

Reputation: 32537

Its because you are not overriding proc method but you are overloading it - that means that you are creating another method with the same name but different arguments list.

The most fitting method will be used.

Upvotes: 0

Andrey Tyukin
Andrey Tyukin

Reputation: 44957

The method

public void proc(Z p) {System.out.println(39);}

in Z does not override

public void proc(X p) {System.out.println(43);}

in X because it restricts the domain to Z instead of X.

However, the analogous method in Y does override proc in X.

Since the compile time type of x is X, the only method signature that matches x.proc(z) is that of public void proc(X p). Only now does the dynamic dispatch take place, and the overriding version from Y is selected and executed, which results in output "57", as expected.

Upvotes: 1

rgettman
rgettman

Reputation: 178293

First, the compiler chooses which method (with signature) to call at compile time first. With method resolution on which signature to call, the compile-time type of the variable is considered; polymorphism doesn't apply here. The compile-time type of x is X, even if it really is a Z object at runtime. Only proc(X) is considered, and that matches, because the z you pass in is an X.

At runtime, polymorphism in Java means that the runtime of the object on which the method is called is taken into consideration for determining which override to call. Y's proc overrides X's proc. However, Z's proc method takes a Z, not an X, so Z's proc method overloads proc; it does not override it. Therefore, Y's proc is chosen.

Upvotes: 0

Related Questions