Java重载解析-为什么是m(强制转换,强制转换)而不是m(匹配,强制转换)

Java重载解析-为什么是m(强制转换,强制转换)而不是m(匹配,强制转换),java,overload-resolution,Java,Overload Resolution,我很确定我不会是第一个被这个问题绊倒的人,但我找不到答案。这是家庭作业 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){

我很确定我不会是第一个被这个问题绊倒的人,但我找不到答案。这是家庭作业

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
    }
}
两次都是Vogel(鸟)(声明和运行时类型)和某种鱼。为什么选择m(Tier,Fisch)而不是m(Vogel,Fisch)

第一个参数将是一个完美的匹配。其余部分符合我的直觉

对不起,如果我只是太麻木了,找不到类似的问题

祝你周末愉快, 斯蒂芬这里:

Vogel v1 = new Vogel();                
Karpfen k = new Karpfen();
...
Super sup2 = new Sub();
...
sup2.m(v1, k);   //4 expected, got 3
sup2
Super
类类型一起声明。
编译器选择的方法依赖于声明变量的类,而不是运行时实例。
因此,编译器在
Super
类中查找匹配的方法

Super
类中,这些是
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");
}
编译器在其他方法中选择最具体的方法,以与声明类型的
v1
k
参数匹配:

选择此方法:

public void m(Tier t, Fisch f){
    System.out.println("2");
}
现在,在运行时,在运行时对象上调用该方法(多态性原则)
由于
sup2
变量引用的运行时类是
Sub
,因此调用了
Sub
的重载方法:

public void m(Tier t1, Fisch t2){
    System.out.println("3");
}
对于第二次调用:

sup2.m(v1, f);  //4 expected, got 3
这是完全相同的推理