Reputation: 131
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
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
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
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