昨天我问了一个类似的问题,但是又出现了另一个问题。
class Cat {
public void isClawedBy(Cat c, Kitten k){
System.out.println("Clawed by a cat");
}
}
class Kitten extends Cat{
public void isClawedBy(Kitten k, Cat c){
System.out.println("Clawed by a Kit");
}
}
Cat g = new Cat();
Cat s = new Kitten();
Kitten t = new Kitten();
g.isClawedBy(s,t);
s.isClawedBy(t,s);
t.isClawedBy(t,t);
我很困惑的问题是关于
t.isClawedBy(t,t);
。我知道s.isClawedBy(t,s);
会引发错误,因为s是静态类型cat。但是
t.isClawedBy(t,t);
抛出“方法isClawedBy(Kitten,Cat)对于小猫类型不明确”错误。如果我将代码更改为t.isClawedBy(s,t);
或t.isClawedBy(t,s);
,它可以工作,但是不确定为什么它不适用于(t,t)。提前致谢
最佳答案
在Java方法中,调用是动态解析的。当您调用方法时,JVM会尝试查找与签名匹配的方法,即方法名称,参数类型和返回类型。它通过查看所用类的方法表来做到这一点,该表还将包含超类型的方法签名。
当检查方法表中的签名是否合适时,它将考虑参数(和返回)类型的超类型。对于t.isClawedBy(t,t)
,我们有两种方法可以匹配,分别是Kitten
匹配中定义的方法和Cat
匹配中定义的方法-请注意,这些方法是不同的方法,因为它们具有不同的参数类型。
由于两个不同的方法匹配,因此方法调用是不明确的。
对于isClawed(s,t)
和isClawed(t,s)
,没有任何歧义,因为s
是小猫,而不能是猫。