JavaでのArrayList間のキャスト
質問
申し訳ありませんが、私は、これは継承の問題だと思った:それはすべてに沿ってArrayListの質問だった。
![OK]を、私の問題は、私は思ったよりも、より具体的です。だから私は、クラスの2人の家族を持っています。カード、およびゾーン。ゾーンは、カードを保持するためのボックスです。
ゾーン、ZoneListとZoneMapの最初の2つのサブクラスは、カードを格納する2つの異なる方法であることを意味しています。こうした手、およびPokerHand、などのさらなるサブクラスでは、彼らは保存のカードを扱う独自の具体的な方法があります。
それは複雑になるカードはまた、PokerCardなどのサブクラスを、持っていること、およびZoneListとZoneMapのサブクラスはこれらを整理するために意図されていることです。
ZoneListにおけるので、私はprotected ArrayList<Card> cardBox;
ているとPokerHandに私はPokerCardがカードであるため、cardBox = new ArrayList<PokerCard>();
を宣言することができると期待しました。私は取得していますエラーが...それはのArrayListに来るとき、私はどうやらカードとGangCardの間でキャストすることはできませんということですだから、僕はPokerHand内部private ArrayList<PokerCard> cardBox;
としてcardBoxを再宣言することによって、この問題を解決しようとしていたが、それは盗聴された隠れになりました私のプログラムアップます。
SO本当に、質問はのArrayListの間のキャストについてですか? Javaは、私はできないと言われますので、上の任意のアイデアをどのようにすることができます?
Z
解決
私が正しくあなたを理解していれば、あなたはおそらく宣言する必要があります:
public class ZoneList<T extends Card> {
protected List<T> cardBox;
}
public class PokerHand extends ZoneList<PokerCard> {
public PokerHand() {
cardBox = new ArrayList<PokerCard>();
}
}
他のヒント
マルクとkolstaeは、問題を回避する方法の面で良い答えを与えているが、私はそれがの理由のあなたの元のコードは動作しません説明する価値があると思います。
の事項を簡素化するために、私は果物の面で問題を置く傾向があります。我々が持っていると仮定します:
List<Banana> bananaBunch = new ArrayList<Banana>();
List<Fruit> fruitBowl = bananBunch;
fruitBowl.add(new Apple());
これが許可されている場合は、、我々は明らかに悪いことであるバナナの房、リンゴで終わります。だから、問題はどこにありますか?最初の行は大丈夫でなければなり、3行目は大丈夫である必要があります - あなたはList<Fruit>
にフルーツの任意の種類を追加することができます - ので、問題は2行目になければなりません。それは、この種の問題を回避するために、正確に、禁止されているものです。
まったくその助けをしていますか?
まず第一に、それはあなたが複雑な継承をたくさんやっているつもりだ場合は特に、直接プロパティにアクセスするよりも、getter / setterメソッドを使用することを練習方が良いでしょう。
ジェネリック医薬品の問題として、あなたはスーパークラス(またはトップレベルのインタフェース/抽象クラス)にcardBoxゲッターを定義試みることができるようにます:
protected ArrayList<? extends Card> getCardBox();
そうすれば、あなたはサブクラスでそれをovverrideし、それらはカードのサブクラスのいずれかのタイプのリストを返すことができます。
これを実行する1つの方法は、最初にArrayListにキャストしている。
ArrayList<Card> cards = (ArrayList<Card>)(ArrayList<?>) (pokerCardObjects);
鋳造せずに、別の代替案ます:
ストリームでます:
ArrayList<Card> cards = pokerCardObjects.stream().collect(Collectors.toCollection(ArrayList::new);
それとも新しいのArrayListを作成します:
ArrayList<Card> cards = new ArrayList<>(pokerCardObjects);
、あなたは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);
}
これは、アクセス制御がZonelist
でArrayListの上にあるものに依存しようとしています。デバッガの文から私の仮定は、それは、マークされていない公共の、または保護のいずれかであるということです。サブクラスは、同じ名前の変数を定義することによってへのアクセス権を持つ親クラスの変数を「隠す」ことができます。また、親を参照するために、特定のオブジェクトインスタンスとthis
キーワードを参照するためにsuper
キーワードを使用することができます。
ここでは、Javaの基本的なアクセス制御には良いリンクがあります:
http://java.sun.com/docs /books/tutorial/java/javaOO/accesscontrol.htmlする
これはあなたにも役立つかもしれません。