2011-01-07 39 views
0

下面是相關的類和方法:子類是否導致類停止實現接口?

public class BoardTile implements BoardCoordinate 

public class WordPath extends LinkedList<BoardTile> 

public void inputCoordinates(Collection<BoardCoordinate> coords) 

基本上,這是怎麼回事是這樣的:我在寫一個機器人的flash遊戲,我有叫BoardCoordinate接口對代表的位置板。一個代表板上瓦片的類被稱爲BoardTile,並且由於它知道它的位置,它實現了BoardCoordinate接口。

我有一個代表板上的路徑,這實際上是一個BoardTiles LinkedList的路徑列表。最後,我有一種方法將一組BoardCoordinates傳遞給我的java.awt.Robot,它將請求的路徑輸入到Flash遊戲。該集合是爲了避免屏幕刮取器類和我的數據處理包之間可能存在的醜陋偶合而傳遞的。

那麼,這裏是有問題的代碼:

/* 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是一個集合!這裏發生了什麼?

當然,我也硬着頭皮接受連接,但首先,這是不是我想要做的,其次,一個學習的機會......

+0

不是你的問題的答案,但我想建議對設計或類命名做一些小改動, BoardTile`是你放置(或者)放置在遊戲地圖或遊戲板上的東西,但是這樣的貼圖不是座標,它有**座標,界面的設計或者命名都應該反映這個「現實世界」財產現在一個小的改變通常會在你嘗試瞭解你自己的代碼後得到回報(個人經驗......) )或一旦你需要傳達你的設計(另一種個人經驗;-))在你的情況下,我會改變設計的構圖。我' – 2011-01-07 07:32:03

回答

3

一個LinkedList<BoardTile>不是Collection<BoardCoordinate>不過,由於一般的差異。例如,考慮:

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

但是,如果沒有實施BoardCoordinate,OtherBoardTile如何成爲BoardTile?它是否不繼承其父方法,從而實現BoardCoordinate? – Alex 2011-01-07 06:49:47

0
class B extends A { ... } 

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

listA = listB; // error 

collectionA = listB; // error 

即使B extends AList<B>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>說法。

但是,有一個問題。 inputCoordinate將能夠從coords中讀取,例如,你可以調用coords.get(i),但它不能將任何東西插入coords(例如,你不能調用coords.add()。更一般地說,因爲? extends XXX,你可以調用返回類型參數的方法(例如XXX get(...)),但是你贏了' t能夠調用任何使用類型參數作爲方法參數類型的方法(例如void add(XXX arg)

相關問題