Java Overload Resolution - Why m (cast, cast) instead of m (match, cast)
I'm sure I can't be the first to stumble on this, but I can't seem to find an answer. This is homework.
class Tier{}
class Fisch extends Tier{}
class Vogel extends Tier{}
class Huhn extends Vogel{}
class Spatz extends Vogel{}
class Karpfen extends Fisch{}
class Super{
public void m(Tier t1, Tier t2){
System.out.println("1");
}
public void m(Tier t, Fisch f){
System.out.println("2");
}
public void m(Fisch f, Tier t){
System.out.println("5");
}
}
class Sub extends Super{
public void m(Tier t1, Fisch t2){
System.out.println("3");
}
public void m(Vogel v, Fisch f){
System.out.println("4");
}
}
public class TierTest{
public static void main(String[] args) {
Tier t1 = new Tier();
Tier t2 = new Vogel();
Fisch f = new Karpfen();
Vogel v1 = new Vogel();
Vogel v2 = new Spatz();
Huhn h = new Huhn();
Karpfen k = new Karpfen();
Super sup1 = new Super();
Super sup2 = new Sub();
sup1.m(h, v2);
sup2.m(v1, k); //4 expected, got 3
sup1.m(t1, t2);
sup1.m(v1, k);
sup1.m(v2, f);
sup2.m(v1, f); //4 expected, got 3
}
}
Both times - Vogel (bird) (runtime declaration and type) and some fish. Why is m (Tier, Fisch) chosen over m (Vogel, Fisch)?
The fist parameter would be a perfect match. The rest is in line with my intuition.
Sorry if I was just numb to find a similar question.
Have a nice weekend, Stephan
source to share
Here:
Vogel v1 = new Vogel();
Karpfen k = new Karpfen();
...
Super sup2 = new Sub();
...
sup2.m(v1, k); //4 expected, got 3
sup2
is declared with a class type Super
.
The method chosen by the compiler depends on the class of the declared variable, not on the runtime instance.
So, compilers are looking for a method that matches a class Super
.
In a class, Super
these are potential method candidates m()
:
public void m(Tier t1, Tier t2){
System.out.println("1");
}
public void m(Tier t, Fisch f){
System.out.println("2");
}
public void m(Fisch f, Tier t){
System.out.println("5");
}
The compiler chooses the most specific method among others to match the declarations v1
and k
declared types:
This method is chosen:
public void m(Tier t, Fisch f){
System.out.println("2");
}
Now, at runtime, the method is called on the runtime object (principle of polymorphism).
Since the runtime class the variable sup2
belongs to Sub
, the overloaded method is called Sub
:
public void m(Tier t1, Fisch t2){
System.out.println("3");
}
And for this second call:
sup2.m(v1, f); //4 expected, got 3
This is exactly the same reasoning.
source to share