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

+3


source to share


1 answer


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.

+3


source







All Articles