昨天我问了一个类似的问题,但是又出现了另一个问题。

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是小猫,而不能是猫。

08-03 13:07