Java 多态性-歧义错误

Java 多态性-歧义错误,java,polymorphism,dispatch,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 Ki

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

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)工作


提前感谢

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

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


要重写方法,参数必须相同。

这是不明确的,因为
Kitten
s是
Cat
s

因此,鉴于:

Cat    isClawedBy(Cat c, Kitten k)
Kitten isClawedBy(Kitten k, Cat c)
对于
小猫
,这两种方法都可用。一只
Kitten
是一只
Cat
,因此使用两个
Kitten
参数调用
Cat.isClawedBy(Cat,Kitten)
符合签名要求。同样地,调用带有两个
Kitten
s的
Kitten.isClawedBy(Kitten,Cat)
也会匹配签名


编译器无法判断要使用哪个方法。

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

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

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


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

kitten扩展了cat,因此kitten获得了cat的属性和方法,因此kitten类知道2种方法

  • 公共空间受法律保护(c类、k类)
  • 公共空间受法律保护(小猫k、猫c)

  • 但是它不知道有一个公共空间是由(小猫k,小猫k)引起的,所以它不知道当你叫它是由(t,t)引起的时候该怎么办

    我喜欢你想要理解的方式,尝试了很多组合:)其他人已经解释过了。只有一个技巧——考虑使用@重写注释来告诉编译器你的意图。您不会感到惊讶,编译器会告诉您并没有重写任何方法。这不仅仅是一个双重匹配-两个候选者匹配得一样好。如果一种方法比另一种方法“更具体”,那么即使有两个匹配项,也会选择它。参见JLS,