简体   繁体   中英

Using ArrayLists in Superclass/Subclass Framework

I have a question about the use of data structures such as ArrayLists in a simple inheritance structure. I'm having a difficult time wording it: hopefully you can understand what I am trying to ask.

I have a Superclass Parrot and a Subclass PirateParrot extending Parrot . In Parrot , I have the following method:

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

Which returns a random string in an ArrayList called sounds which is created in the Parrot class.

If I create a separate instance of PirateParrot called polly , which also has its own ArrayList, and try to call polly.speak(); without any implicit implementation for the speak method in the PirateParrot class, I get thrown an "Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 0, Size: 0"

If I specifically copy/paste in the speak() method from Parrot into PirateParrot , the code compiles fine and runs properly. What exactly was the problem previously? Is there a way to make this run correctly without having to copy/paste the speak() method into PirateParrot ? Thanks!

If I understand the problem correctly, then the simplest fix would be to not declare another sounds variable in PirateParrot . Instead, make sure sounds is declared protected in Parrot , and then in the PirateParrot constructor just populate the inherited sounds variable with whatever sounds you want the PirateParrot to have.

Another alternative might be to have a getSounds() method that returns the list and call getSounds() from inside of speak() instead of referencing sounds directly. Then PirateParrot would just need to override getSounds() to return its version of sounds .

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);
  }
}

You are not initializing and populating the sounds before calling it, do the following:
initialize and populate sounds in the constructor of PirateParrot and then call superclass ' speak method.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM