Java 重载分辨率 - 为什么是 m(cast, cast) 而不是 m(match, cast)



我很确定我不能成为第一个偶然发现这个问题的人,但我找不到答案。这是家庭作业。

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");
}

编译器选择最具体的方法,以匹配v1k声明类型的参数:

选择此方法:

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

这是完全相同的推理。

相关内容

  • 没有找到相关文章

最新更新