1

単純な継承構造でのArrayListsなどのデータ構造の使用について質問があります。私はそれを表現するのに苦労しています:うまくいけば、あなたは私が尋ねようとしていることを理解することができます。

を拡張するスーパークラスParrotとサブクラスがあります。では、次の方法があります。PirateParrotParrotParrot

 public String speak() {
     int rand = (int)(Math.random() * sounds.size());
     return sounds.get(rand);
    }

これは、クラスsoundsで作成されたと呼ばれるArrayList内のランダムな文字列を返します。Parrot

独自のArrayListを持つPirateParrotcalledの別のインスタンスを作成し、クラスのspeakメソッドを暗黙的に実装せずに呼び出そうとすると、 「スレッド内の例外」main「java.lang.IndexOutOfBoundsException:Index」がスローされます。 :0、サイズ:0pollypolly.speak();PirateParrot

特にspeak()メソッドをからにコピーして貼り付けると、コードは正常にコンパイルされ、正しく実行されますParrotPirateParrot以前の問題は正確には何でしたか?talk()メソッドをコピーして貼り付けることなく、これを正しく実行する方法はありPirateParrotますか?ありがとう!

4

3 に答える 3

3

問題を正しく理解している場合、最も簡単な修正は、で別のsounds変数を宣言しないことですPirateParrot。代わりに、soundsで宣言さprotectedれていることを確認しParrotてから、PirateParrotコンストラクターで、継承されたsounds変数に必要なサウンドを入力するだけですPirateParrot

もう1つの方法は、リストを返し、直接参照するのではなく、内部からgetSounds()呼び出すメソッドを用意することです。次に、そのバージョンを返すためにオーバーライドする必要があります。getSounds()speak()soundsPirateParrotgetSounds()sounds

于 2012-04-11T05:45:16.717 に答える
1
public class Parrot {
  private final ArrayList<String> sounds;

  private static ArrayList<String> REGULAR_PARROT_SOUNDS = new ArrayList<String>();
  static {
    REGULAR_PARROT_SOUNDS.add(...);
    ...
  }

  protected Parrot(ArrayList<String> sounds) {
    this.sounds = sounds;
  }

  public Parrot() {
    this(REGULAR_PARROT_SOUNDS);
  }
}

public class PirateParrot {
  private static ArrayList<String> PIRATE_PARROT_SOUNDS = ...;

  public PirateParrot() {
    super(PIRATE_PARROT_SOUNDS);
  }
}
于 2012-04-11T05:52:24.720 に答える
1

soundsを呼び出す前に初期化してデータを入力するのではなく、次の手順を実行します。
を初期化してデータを入力soundsしてconstructorから、スーパークラスのメソッドPirateParrotを呼び出します。speak

于 2012-04-11T05:52:28.133 に答える