多态性 - 模糊错误

时间:2013-06-10 22:56:11

标签: java polymorphism dispatch

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

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)对于类型Kitten”的错误是不明确的。如果我将代码更改为t.isClawedBy(s,t);t.isClawedBy(t,s);它可以正常工作,但不确定它为什么不适用于(t,t)。

提前致谢

4 个答案:

答案 0 :(得分:1)

这是不明确的,因为KittenCat s。

因此,给定:

Cat    isClawedBy(Cat c, Kitten k)
Kitten isClawedBy(Kitten k, Cat c)

对于Kitten,两种方法都可用。 KittenCat,因此使用两个Cat.isClawedBy(Cat, Kitten)参数调用Kitten符合签名。同样,使用两个Kitten.isClawedBy(Kitten, Cat)的{​​{1}}调用也会与签名匹配。

编译器无法确定预期的方法。

答案 1 :(得分:1)

在Java中,方法调用是动态解析的。当您调用方法时,JVM会尝试查找与签名匹配的方法,即方法名称,参数类型和返回类型。它通过查看所用类的方法表来完成此操作,该方法表还将包含超类型的方法签名。

当检查方法表中的签名是否合适时,它将考虑参数(和返回)类型的超类型。在t.isClawedBy(t,t)的情况下,我们有两个方法可以匹配Kitten匹配中定义的方法和Cat匹配中定义的方法 - 请注意这些方法是不同的方法,因为它们具有不同的参数类型

由于两种不同的方法匹配方法,因此调用不明确

对于isClawed(s,t)isClawed(t,s),没有歧义,因为s是小猫,不能是猫。

答案 2 :(得分:0)

这是因为你没有覆盖那个方法。

对于t.isClawedBy(t,t);,有两种可能的方法可以执行.Cat的isclawed方法和小猫的isclawed方法。

要覆盖方法,参数必须相同。

答案 3 :(得分:0)

小猫延伸猫,所以小猫得到猫的atributs和方法,所以小猫类知道2种方法

  1. public void isClawedBy(Cat c,Kitten k)
  2. public void isClawedBy(Kitten k,Cat c)
  3. 但是它知道一个公共的空洞是否被犯罪(小猫k,小猫k)所以当你打电话给isClawedBy(t,t)时它知道该怎么做;