public class Animal {}
public class Bird extends Animal {}
public class Mamal extends Animal {}
public class Human extends Mamal {}
public class Main {
public void Hungry(Mamal mamal){
System.out.println("Mammal");
}
public void Hungry(Human human){
System.out.println("Human");
}
public void Hungry(Bird bird){
System.out.println("Bird");
}
public static void main(String a[]){
Main main = new Main();
main.Hungry(null);
}
编译器说Hungry(Mamal)的方法含糊不清。 我希望执行“人类”方法,因为它是最低级别。我没有从http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.12
中找到歧义的原因答案 0 :(得分:11)
Human
和Bird
在继承层次结构中处于同一级别(尽管不是在视觉上)。或者将它们视为完全不相关的引用类型。因此,一个并不比另一个更具体。
如果删除Hungry(Bird)
方法,则代码将编译。
更具体的规则是here。
一个名为m的固定成员方法比另一个更具体 如果以下所有内容的同名成员方法和arity 条件成立:
第一个成员方法的参数的声明类型是 T1,...,Tn。
其他方法的参数的声明类型是U1,..., 未
如果第二种方法是通用的,那么让R1 ... Rp(p≥1)为其 类型参数,设B1为Rl的声明边界(1≤l≤p),let A1 ... Ap是推断的类型参数(第15.12.2.7节) 在初始约束条件下调用Ti<< Ui(1≤i≤n),让 Si = Ui [R1 = A1,...,Rp = Ap](1≤i≤n)。
否则,让Si = Ui(1≤i≤n)。
对于从1到n的所有j,Tj&lt ;: Sj。
如果第二种方法是如上所述的通用方法,那么Al <:Bl [R1 = A1,...,Rp = Ap](1≤l≤p)。
所以你有
public void Hungry(Human human){
System.out.println("Human");
}
public void Hungry(Bird bird){
System.out.println("Bird");
}
因此Human
为T1
而Bird
为U1
(也会尝试相反)。方法不通用。
S1 = U1
对于从i到n(1到1)的所有j
,这应该成立:Ti <: Si
,其中<:
是
我们写T&lt;:S表示子类型关系在类型T和S之间成立。
这不适用于我们的两种方法,因为Human
不是Bird
的子类型,反之亦然,因此没有更具体的方法来调用,即。歧义。
就像你有
一样void method(String s){}
void method(RandomReferenceType t) {}
并试图致电
method(null);
答案 1 :(得分:2)
由于null
没有与之关联的类型,编译器不知道应该调用哪个hungry
方法;因此,它是不明确的&#34;。要消除它的歧义,只需投下它:
public class Main {
public void hungry(Mamal mamal){
System.out.println("Mammal");
}
public void hungry(Human human){
System.out.println("Human");
}
public void hungry(Bird bird){
System.out.println("Bird");
}
public static void main(String a[]){
Main main = new Main();
main.hungry((Mamal)null);
}
}
class Animal {}
class Bird extends Animal {}
class Mamal extends Animal {}
class Human extends Mamal {}
答案 2 :(得分:2)
amibuity是因为您有三个具有相同名称的方法,并且您传递的是null值。编译器不知道您调用的是哪种方法。只需写一个ie public void hungry(Animal animal)
并检查里面动物的类型。例如if(animal instanceof Bird) { System.out.println("Bird") ....
。
还要将方法名称更改为小写。有时编译器会失败。