2013-06-10 5 views
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가 정적 유형 cat이기 때문에 s.isClawedBy(t,s);이 오류를 발생시키는 것을 알고 있습니다.

그러나 t.isClawedBy(t,t);은 "Kitten 유형에 대해 isClawedBy (Kitten, Cat) 메소드가 모호합니다."라는 오류가 발생합니다. 내가 코드를 t.isClawedBy(s,t); 또는 t.isClawedBy(t,s);으로 변경하면 작동하지만, (t, t)가 작동하지 않는 이유는 확실하지 않습니다.

미리 감사드립니다.

+0

나는 많은 조합을 시도하면서 이해하려는 방식을 좋아합니다. – nachokk

+0

다른 사람들은 이미 설명했습니다. 팁 하나만 - @Override 주석을 사용하여 컴파일러에 의도를 알리는 것을 고려하십시오. 당신은 놀라지 않을 것이고 컴파일러는 당신이 어떤 방법보다 우선하지 않는다고 말할 것입니다. – wjtk

답변

1

Java 메소드 호출은 동적으로 해결됩니다. 메소드를 호출하면 JVM은 메소드 이름, 매개 변수 유형 및 리턴 유형과 같은 서명과 일치하는 메소드를 찾으려고 시도합니다. 이것은 슈퍼 타입의 메소드 시그니처도 포함 할 사용 된 클래스의 메소드 테이블을보고이를 수행합니다.

메서드 테이블의 서명이 적합한 지 확인하는 경우 매개 변수 (및 반환) 형식의 수퍼 유형을 고려합니다. t.isClawedBy(t,t)의 경우 Kitten에 정의 된 메소드와 Cat에 정의 된 메소드가 일치 할 수있는 두 가지 메소드가 있습니다. 매개 변수 유형이 서로 다른 다른 메소드입니다.

두 가지 다른 메서드가 일치하는 경우 은 모호하므로입니다.

isClawed(s,t)isClawed(t,s)의 경우 s은 고양이이므로 고양이가 될 수 없으므로 애매 모호하지 않습니다.

+0

그것은 단지 두 번 일치하는 것이 아닙니다. 두 후보가 똑같이 잘 맞습니다. 하나의 방법이 다른 것보다 "더 구체적"이었다면 두 개의 일치가 있더라도 선택되었을 것입니다. JLS [15.12.2.5 가장 구체적인 방법 선택] (http://docs.oracle.com/javase/specs/jls/se5.0/html/expressions.html#15.12.2.5)을 참조하십시오. –

0

해당 방법을 재정의하지 않았기 때문입니다.

t.isClawedBy(t,t);에는 실행 가능한 두 가지 방법이 있습니다. Cat의 isclawed 메소드와 Kitten의 isclawed 메소드.

방법을 재정의하려면 매개 변수가 동일해야합니다.

1

KittenCat이기 때문에 모호합니다.

따라서, 주어진하십시오 Kitten 들어

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

은 두 가지 방법이 가능하다. A KittenCat이므로 Kitten 인수가있는 Cat.isClawedBy(Cat, Kitten)을 호출하면 서명이 적합합니다. 마찬가지로 Kitten이 두 개인 Kitten.isClawedBy(Kitten, Cat)을 호출해도 서명이 일치합니다.

컴파일러가 의도 된 방법을 알 수있는 방법이 없습니다.

0

새끼 고양이를 확장, 그래서 고양이가 atributs 고양이의 방법을 얻을, 그래서 고양이 클래스는이 방법

을 알고
  1. 공공 무효 isClawedBy (고양이 C, 새끼 고양이 k)는
  2. 공공 무효 isClawedBy (고양이 K, Cat c)

그러나 metoth public void isClawedBy (Kitten k, Kitten k)를 알고 있으므로, isClawedBy (t, t)를 호출 할 때 수행 할 작업을 알고 있습니다.