2

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

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

4 回答 4

1

它是模棱两可的,因为Kittens 是Cats。

因此,给定:

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

对于 a Kitten,两种方法都可用。AKitten是 a Cat,因此Cat.isClawedBy(Cat, Kitten)带有两个Kitten参数的调用符合签名。同样,Kitten.isClawedBy(Kitten, Cat)带有两个Kittens 的调用也匹配签名。

编译器无法分辨出要使用哪种方法。

于 2013-06-10T23:05:09.310 回答
1

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

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

由于两种不同的方法匹配,方法调用是模棱两可的。

因为没有像小猫一样的模棱两可isClawed(s,t),也不能是猫。isClawed(t,s)s

于 2013-06-10T23:07:35.660 回答
0

kitten继承了cat,所以kitten得到了cat的属性和方法,所以kitten类知道2个方法

  1. public void isClawedBy(Cat c, Kitten k)
  2. 公共无效 isClawedBy(小猫 k,猫 c)

但是它不知道一个方法 public void isClawedBy(Kitten k, Kitten k) 所以当你调用 isClawedBy(t,t); 时它不知道该怎么做;

于 2013-06-10T23:41:30.270 回答
0

这是因为您没有覆盖该方法。

因为t.isClawedBy(t,t);有两种可能的方法来执行。猫的爪法和小猫的爪法。

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

于 2013-06-10T23:05:00.513 回答