2008-12-11 68 views
8

對不起,我認爲這是一個繼承問題:它始終是一個ArrayList問題!在Java中的ArrayList之間進行Casting

好吧,我的問題比我想象的更具體。所以我有兩個班的家庭。卡和區域。區域是拿着卡片的盒子。

Zone的前兩個子類,ZoneList和ZoneMap意味着存儲卡的兩種不同方式。更多的子類,例如Hand和PokerHand,都有自己特定的處理卡片的方式。

如果它變得複雜的是,卡也有子類,例如撲克卡,並且ZoneList和ZoneMap的子類是用來組織這些子類的。

所以在ZoneList中我有protected ArrayList<Card> cardBox;和PokerHand,因爲PokerCard是一張卡片,所以我希望能夠申報cardBox = new ArrayList<PokerCard>();。我得到的錯誤是我顯然無法在CardLists和GangCard之間進行ArrayLists ...所以我試圖通過在PokerHand中重新聲明cardBox爲private ArrayList<PokerCard> cardBox;來解決此問題,但導致隱藏的是竊聽啓動我的程序。

所以,真的,問題是關於在ArrayLists之間進行投射嗎? Java告訴我我不能,所以我有什麼想法?

z。

+0

試想想吧!我認爲另一種情況是類似的,當我調用getElementAt();它回到了我的GImage,我不能像GImage那樣對待!當我嘗試調用GImage.getName()時,Java獲得了所有的支持。或什麼的,因爲它不是一個圖像它是一個對象...! – Ziggy 2008-12-11 06:19:25

回答

11

如果我理解正確的話,你應該聲明:

public class ZoneList<T extends Card> { 
    protected List<T> cardBox; 
} 

public class PokerHand extends ZoneList<PokerCard> { 
    public PokerHand() { 
     cardBox = new ArrayList<PokerCard>(); 
    } 
} 
+0

哦,夥計!太好了。我完全一直在想「如果我知道如何將類型作爲參數傳遞,這不會很好嗎?」而現在我完全可以做到!朋友! – Ziggy 2008-12-11 07:12:59

1

這將取決於Zonelist中的Arraylist上的訪問控制。我從調試器聲明中得出的假設是它是未標記的,公共的或受保護的。子類可以通過定義具有相同名稱的變量來「隱藏」它可以訪問的父類變量。您還可以使用this關鍵字來引用特定對象實例,並使用super關鍵字來引用父對象。

這裏是Java基本訪問控制的很好的鏈接:

http://java.sun.com/docs/books/tutorial/java/javaOO/accesscontrol.html

這個你也可能會發現有用的

http://java.sys-con.com/node/46344

+0

我不認爲這是一個訪問控制問題 - 這是一個通用的方差問題。 – 2008-12-11 07:49:02

10

首先,它通常是更好的做法是使用getter/setter方法,而不是直接訪問屬性,特別是如果你要做很多複雜的繼承。

對於仿製藥的問題,你可以嘗試定義cardBox吸氣劑超(或頂層接口/抽象類)爲:

protected ArrayList<? extends Card> getCardBox(); 

這樣,你可以在子類中ovverride它,並讓他們返回Card的任何類型的子類的列表。

+0

啊!我不知道我能做到這一點:太棒了!謝謝! – Ziggy 2008-12-11 07:11:54

+0

當使用這個<?擴展Card> thingy,我應該如何去初始化ArrayLists?只是普通的舊盒子=新的ArrayList ();返回我一個錯誤?... – Ziggy 2008-12-11 09:08:08

+1

在子類中,您將實例化一個列表作爲屬性,其中'private final列表 cardBox = new ArrayList ()'此列表將由getCardBox方法返回。 – boutta 2008-12-11 09:57:15

19

Marc和kolstae在如何解決這個問題方面都給予很好的答案,但我認爲這是值得說明的是爲什麼你原來的代碼不起作用。

爲了簡化問題,我傾向於把問題放在水果方面。假設我們有:

List<Banana> bananaBunch = new ArrayList<Banana>(); 
List<Fruit> fruitBowl = bananBunch; 
fruitBowl.add(new Apple()); 

如果這是允許的,我們最終在一串香蕉,這顯然是一件壞事,一個蘋果。那麼,問題在哪裏?第一行必須沒問題,第三行必須沒問題 - 你可以添加任何種類的水果到List<Fruit> - 所以問題必須在第二行。這是禁止的,正是爲了避免這種問題。

這有幫助嗎?

6

如上所述,您不能將ArrayList<PokerCard>轉換爲ArrayList<Card>,但您可以將ArrayList<PokerCard>轉換爲ArrayList<? extends Card>。或者更好的使用List<? extends Card>爲您的返回值,因爲你可能不依賴於該ArrayList實現反正:

protected ArrayList<? extends Card> getCardBox(); 

至於在評論你的問題,因爲你描述的結構應該工作:List<? extends Card> list = new ArrayList<Card>();。你可能需要填寫你的列表中,因此該方法可能是這樣的:

protected ArrayList<? extends Card> getCardBox() { 
    List<Card> list = new ArrayList<Card>(); 
    list.add(pokerCard1); 
    list.add(pokerCard2); 
    return java.util.Collections.unmodifiableList(list); 
} 
4

的一種方式做到這一點是鑄造最早ArrayList的:

ArrayList<Card> cards= (ArrayList<Card>)(ArrayList<?>) (PokerCardObject);