简体   繁体   English

在超类/子类框架中使用 ArrayLists

[英]Using ArrayLists in Superclass/Subclass Framework

I have a question about the use of data structures such as ArrayLists in a simple inheritance structure.我有一个关于在简单的 inheritance 结构中使用 ArrayLists 等数据结构的问题。 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 .我有一个超类Parrot和一个扩展Parrot的子类PirateParrot In Parrot , I have the following method:Parrot中,我有以下方法:

 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.它返回一个名为sounds的随机字符串,该字符串是在Parrot class 中创建的。

If I create a separate instance of PirateParrot called polly , which also has its own ArrayList, and try to call polly.speak();如果我创建一个名为polly的独立PirateParrot实例,它也有自己的 ArrayList,并尝试调用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" PirateParrot class 中的 speak 方法没有任何隐式实现,我抛出“线程“主”java.lang.IndexOutOfBoundsException 中的异常:索引:0,大小:0”

If I specifically copy/paste in the speak() method from Parrot into PirateParrot , the code compiles fine and runs properly.如果我专门将Parrot中的 speak() 方法复制/粘贴到PirateParrot中,则代码可以正常编译并正常运行。 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 ?有没有办法使它正确运行而不必将 speak() 方法复制/粘贴到PirateParrot Thanks!谢谢!

If I understand the problem correctly, then the simplest fix would be to not declare another sounds variable in PirateParrot .如果我正确理解了问题,那么最简单的解决方法就是不在PirateParrot中声明另一个sounds变量。 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.相反,请确保soundsParrot中被声明为protected ,然后在PirateParrot构造函数中只需使用您希望PirateParrot具有的任何声音填充继承的sounds变量。

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.另一种选择可能是使用getSounds()方法返回列表并从speak()内部调用getSounds() ) 而不是直接引用sounds Then PirateParrot would just need to override getSounds() to return its version of sounds .然后PirateParrot只需要覆盖getSounds()来返回它的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:在调用它之前,您没有初始化和填充sounds ,请执行以下操作:
initialize and populate sounds in the constructor of PirateParrot and then call superclass ' speak method.PirateParrotconstructor中初始化并填充sounds ,然后调用超类speak方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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