2011-01-07 3 views
0

가 여기에 해당 클래스와 메소드이다 : 나는 플래시 게임 봇을 쓰고 있어요, 나는이의 위치를 ​​나타내는 BoardCoordinate라는 인터페이스를 가지고 : 기본적으로하위 클래스로 인해 클래스가 인터페이스 구현을 중단하게합니까?

public class BoardTile implements BoardCoordinate 

public class WordPath extends LinkedList<BoardTile> 

public void inputCoordinates(Collection<BoardCoordinate> coords) 

, 여기에서 일어나고있는 것은 이것이다 판. 보드의 타일을 나타내는 클래스를 BoardTile이라고하며 위치를 알고 있기 때문에 BoardCoordinate 인터페이스를 구현합니다.

저는 실제로 BoardTiles의 LinkedList 인 보드상의 경로를 나타내는 타일 목록을 가지고 있습니다. 마지막으로, 필자는 BoardCoordinates 콜렉션을 java.awt.Robot에 전달하여 플래시 게임에 요청 된 경로를 입력하는 메소드를 가지고있다. 컬렉션은 스크린 스크래퍼 클래스와 데이터 처리 패키지 사이의 잠재적 인 추악한 연결을 피하기 위해 통과되었습니다.

/* The highest scoring path found. */ 
Wordpath highest = null; 
/* ... 
* ... find the highest scoring path, etc. 
*/ 
if (longest != null) { 
    screen.inputCoordinates(longest); 
} 

내가받을 컴파일러 오류가 이것이다 : 유형 화면에서 메소드 inputCoordinates (컬렉션) 인수 (WordPath) 적용 할 수 없습니다

그래서 다음, 여기에 잘못된 코드입니다.

그러나 WordPath는 BoardCoordinate의 LinkedList입니다! 그리고 LinkedList는 Collection입니다! 무슨 일 이니?

은 물론, I는 LinkedList<BoardTile> 비록 Collection<BoardCoordinate> 아니지만 ...

+0

질문에 대한 답변이 아니지만 디자인이나 클래스 이름 지정에 약간의 변경을 제안하고 싶습니다. 보드 타일 (BoardTile)은 게임 맵이나 게임 보드에 놓기 (또는 가지고있는 것)하지만, 타일은 좌표가 아니며 ** 좌표는 ** 좌표입니다. 인터페이스의 디자인이나 이름은 이것을 반영해야합니다 "현실 세계"속성. 작은 변화는 이제 보통 나중에 자신의 코드 (개인적인 경험을 이해하려고 할 때 지불합니다 ...) 또는 일단 디자인에 대한 의사 소통의 필요성을 느끼면 (다른 개인적인 경험 ;-)) 나는 디자인을 구성으로 바꿀 것입니다. 나는 ' –

답변

3

을 총알을 물고 커플 링을 받아, 그러나 이것은 내가, 둘째, 학습 기회를 수행 할 무엇을 먼저하지 수 일반적인 분산으로 인해 예를 들어, 고려 :

collection.add(new OtherBoardCoordinate()); 

OtherBoardCoordinateBoardCoordinate 아니지만 BoardTile입니다. 연결된 목록에있는 사람들 중 하나는 원하지 않을 것입니다.

inputCoordinates 경우에만 에 다음과 같은 자사의 서명을 수정 컬렉션에서을 읽을 필요가 :

public void inputCoordinates(Collection<? extends BoardCoordinate> coords) 

기본적으로 "인수는 BoardCoordinate를 확장 어떤 종류의 집합이어야한다라고하지만, 나는 그 타입이 무엇인지 정확히 신경 쓰지 않는다. " inputCoordinates 내에서 컬렉션에 항목을 추가 할 수 없으므로 처음에 언급 한 문제를 방지 할 수 있습니다.

자세한 내용은 Angelika Langer's Java Generics FAQ을 참조하십시오 ("와일드 카드"참조).

대안은 WordPath 대신 LinkedList<BoardCoordinate>을 확장하는 것입니다, 그냥 그것에 BoardTile 값을 추가을 발생합니다. (당신은 확실히 아마 그러나 귀하의 경우에 해당합니다. 나는 거의 컬렉션 클래스를 확장 자신을 발견하지? 그런데,LinkedList을 확장 해야합니까.)

+0

하지만 BoardBoard를 구현하지 않고 OtherBoardTile을 BoardTile로 만들 수 있습니까? 부모의 방법을 상속받지 않아 BoardCoordinate를 구현합니까? – Alex

+0

@Alex : 죄송합니다. 나는 잘못 돌아왔다. BoardTile이 아닌 OtherBoardCoordinate 여야합니다. –

0
class B extends A { ... } 

Collection<A> collectionA; 
List<A> listA; 
List<B> listB; 

listA = listB; // error 

collectionA = listB; // error 

에도 B extends A 불구하고, List<B>하지 A는 서브 클래스는 List<A>입니다. List<B>Collection<A>의 하위 클래스가 아닙니다.

처음에는 반 직관적입니다. 그것에 대해 생각하는 방법은 다음과 같습니다 당신이 위의 예에서 List<A> 대신에 Collection<A>를 대체 할 경우

List<A> listA; 
// This declaration means that listA promises to point to a List that 
// accepts any instance of 'A' or subclasses of 'A' 

List<A> listA = new List<A>(); 
listA.add(new A()); 
// this is legal because listA promises to put to lists that accept 'A's 

List<B> listB = new List<B>(); 
// new List<B>() creates a list that can hold only instances 
// of 'B' or subclasses of 'B' 

listA = listB; 
// error - broken promise - allowing this assignment would means listA 
// will now point to a list that will *NOT* accept an 'A', in direct 
// conflict with what is promised by its listA's declaration 

listA.add(new A()); 
// if the above assignment were allowed, then this line would allow 
// an `A` to be added to a list that can only hold `B`s 

void myMethod(List<A> listA) { } 

myMethod(listB); 
// error - broken promise - allowing this parameter would means listA 
// (in myMethod) will now point to a list that will *NOT* accept an 'A', 
// in direct conflict with what is promised by its listA's declaration 

같은 인수가 보유하고 있습니다.


하지만 가능한 솔루션이 있습니다. screen 만 수집 coords에서 읽을 경우

, 다음 와일드 카드를 사용하여 작동합니다 :

public void inputCoordinates(Collection<? extends BoardCoordinate> coords) 

inputCoordinate 지금 List<BoardTile> 인수를 받아 들일 것입니다.

그러나 캐치가 있습니다. inputCoordinatecoords에서 읽을 수 있습니다. coords.get(i)으로 전화 할 수는 있지만 coords.add()은 호출 할 수 없습니다. ? extends XXX으로 인해 일반적으로 유형 매개 변수 (예 : XXX get(...))를 반환하는 메소드를 호출 할 수 있지만 ' 메서드 매개 변수 유형 (예 : void add(XXX arg))으로 type 매개 변수를 사용하는 모든 메서드를 호출 할 수 있어야합니다.

관련 문제