8

申し訳ありませんが、これは継承の質問だと思いました。ずっとArrayListの質問でした。

わかりました、私の問題は私が思っていたよりも具体的です。だから私は2つのクラスの家族を持っています。カード、およびゾーン。ゾーンはカードを保持するためのボックスです。

Zoneの最初の2つのサブクラス、ZoneListとZoneMapは、カードを保存する2つの異なる方法を意味します。HandやPokerHandなどのサブクラスには、保存するカードを処理する独自の方法があります。

複雑になるのは、CardにもPokerCardなどのサブクラスがあり、ZoneListとZoneMapのサブクラスはそれらを整理するためのものであるということです。

したがって、ZoneListには、PokerCardがカードであるため、PokerHandでprotected ArrayList<Card> cardBox;宣言できると期待していましcardBox = new ArrayList<PokerCard>();た。私が得ているエラーは、ArrayListsに関してはCardとGangCardの間でキャストできないようだということです...そこで、PokerHandprivate ArrayList<PokerCard> cardBox;内でcardBoxを再宣言するだけでこれを修正しようとしましたが、その結果、隠れていてバグが発生していました私のプログラム。

本当に、問題はArrayLists間のキャストについてですか?Javaは私にできないと言っているので、私ができる方法について何かアイデアはありますか?

z。

4

6 に答える 6

19

Marc と kolstae は、問題を回避する方法に関して適切な回答を提供していますが、元のコードが機能しない理由を説明する価値があると思います。

問題を単純化するために、私は問題を果物の観点から説明する傾向があります。次があるとします。

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

これが許されると、バナナの束の中にリンゴが入ったままになってしまいます。これは明らかに悪いことです。では、どこに問題があるのでしょうか。最初の行は大丈夫でなければならず、3 番目の行も大丈夫でなければなりません - どんな種類の果物でも追加できますList<Fruit>- だから、問題は 2 番目の行になければなりません。それは、まさにこの種の問題を回避するために禁止されていることです。

それはまったく役に立ちますか?

于 2008-12-11T07:23:07.030 に答える
12

私があなたを正しく理解していれば、おそらく次のように宣言する必要があります。

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

public class PokerHand extends ZoneList<PokerCard> {
   public PokerHand() {
      cardBox = new ArrayList<PokerCard>();
   }
}
于 2008-12-11T07:10:18.320 に答える
11

まず第一に、特に多くの複雑な継承を行う場合は、プロパティに直接アクセスするよりも、通常、getter/setterメソッドを使用することをお勧めします。

ジェネリックスの問題については、スーパークラス(またはトップレベルのインターフェイス/抽象クラス)でcardBoxゲッターを次のように定義してみてください。

protected ArrayList<? extends Card> getCardBox();

そうすれば、サブクラスでそれをovverrideし、Cardの任意のタイプのサブクラスのリストを返すようにすることができます。

于 2008-12-11T07:09:34.237 に答える
7

前述のように、にキャストすることはできませんがArrayList<PokerCard>、にキャストすることArrayList<Card>はできます。または、とにかくArrayList実装に依存しない可能性があるため、戻り値として使用することをお勧めします。ArrayList<PokerCard>ArrayList<? extends Card>List<? extends Card>

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);
}
于 2008-12-11T09:43:59.773 に答える
1

これは、のArraylistにあるアクセス制御に依存しますZonelist。デバッガーステートメントからの私の仮定は、それがマークされていないか、公開されているか、保護されているかのいずれかであるということです。サブクラスは、同じ名前の変数を定義することにより、アクセスできる親クラスの変数を「非表示」にすることができます。thisキーワードを使用して特定のオブジェクトインスタンスsuperを参照し、キーワードを使用して親を参照することもできます。

Javaの基本的なアクセス制御に関する適切なリンクは次のとおりです。

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

これも役立つかもしれません

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

于 2008-12-11T06:32:01.580 に答える