假設我們有一個包含這樣的類的程序:Java集合協方差問題
public interface AbstractItem {
}
public SharpItem implements AbstractItem {
}
public BluntItem implements AbstractItem {
}
public interface AbstractToolbox {
//well the problem starts here...
public List<AbstractItem> getItems();
}
public ExpensiveToolbox implements AbstractToolbox {
private List<SharpItem> items = new ArrayList()<SharpItems>;
public List<SharpItem> getItems() { return this.items; }
}
public CheapTooblox implements AbstractToolbox {
private List<BluntItem> items = new ArrayList()<BluntItem>;
public List<BluntItem> getItems() { return this.items; }
}
容易,對不對?那麼可以說,我們現在要做出這樣的方法(在一些隨機類):
public void doImportantStuff(AbstractToolbox toolbox) {
//important stuff!
//this obviously won't work
List<AbstractToolbox> items = toolbox.getItems();
//do some stuffwith all items
}
現在的問題是,在Java的泛型集合不是協變的(希望這是我要找的術語),我不能將ArrayList<ExpensiveToolbox>
分配給List<AbstractToolbox>
。我在這裏可以看到的唯一解決方案是複製代碼併爲每種類型做一個版本,但是這顯然會吸引人(如果我們有更多的類使用不同的列表實現AbstractToolbox?)。顯然,第二種解決方案是放棄泛型並制定一個正常的列表,但這是一個好習慣嗎?
是否有任何解決此類問題的設計模式/實踐?
@編輯:好吧,所以我可能不夠精確。我希望擴展AbstractToolbox的所有類都有一個擴展AbstractItem的特定類的列表,然後我需要一個將AbstractToolbox作爲參數並對列表中的項執行一些操作的方法(使用將在其中定義的類AbstractItem使每個可能的列表中的所有項目都會有它們)。
爲了澄清,你會不會想你doImportantStuff有: 名單項目= toolbox.getIems(); –
MikeTheReader
2010-09-21 18:21:04
你是什麼意思,「容易,對嗎?」你的第一部分不編譯,不應該! – 2010-09-21 18:22:04
那麼我認爲這將是容易的。我的意思很明顯*我*有問題;) – 2010-09-21 18:25:52