2012-04-11 10 views
1

Ich habe eine Frage über die Verwendung von Datenstrukturen wie ArrayLists in einer einfachen Vererbungsstruktur. Es fällt mir schwer, es zu formulieren: Hoffentlich kannst du verstehen, was ich zu fragen versuche.Verwenden von ArrayLists in Superklasse/Unterklassenframework

Ich habe eine Superklasse Parrot und eine Subklasse PirateParrot Erweiterung Parrot. In Parrot habe ich die folgende Methode:

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

, die eine zufällige Zeichenfolge in einer Arraylist zurück sounds genannt, die in der Parrot Klasse erstellt wird.

Wenn ich eine separate Instanz von PirateParrot schaffen polly genannt, was auch seine eigene Arraylist hat, und versuchen polly.speak(); ohne implizite Implementierung für die sprechen Methode aufzurufen in der PirateParrot Klasse, erhalte ich eine „Exception in thread“ geworfen main“java.lang.IndexOutOfBoundsException: Index: 0, Größe: 0"

Wenn ich speziell kopieren/einfügen in der Methode sprich() von Parrot in PirateParrot, wird der Code kompiliert fein und läuft einwandfrei. Was genau war das Problem zuvor? Gibt es eine Möglichkeit, dies korrekt auszuführen, ohne die speak() -Methode in PirateParrot kopieren/einfügen zu müssen? Vielen Dank!

+1

FYI, es ist fast sicher besser, 'Random.nextInt (sounds.size())' 'zu verwenden, was auch den Nebeneffekt haben würde, eine Ausnahme auszulösen, wenn' Sounds' leer ist - was zu sein scheint. –

+0

Okay, ja, ich war mir nicht sicher über die richtige Syntax für Math.Random - danke. –

Antwort

3

Wenn ich das Problem richtig verstehe, dann wäre die einfachste Lösung, keine sounds Variable in PirateParrot zu deklarieren. Stellen Sie stattdessen sicher, dass soundsprotected in Parrot deklariert ist, und dann in dem PirateParrot-Konstruktor einfach die vererbte sounds Variable mit allem, was Sie wollen, die PirateParrot zu haben.

Eine weitere Alternative könnte eine getSounds() Methode zu haben sein, die die Liste zurück und ruft getSounds() von innen speak() statt sounds direkt zu referenzieren. Dann müsste PirateParrot nur getSounds() überschreiben, um seine Version sounds zurückzugeben.

+0

Arbeitete perfekt. Ich habe das geschützte Schlüsselwort nie verwendet. Vielen Dank! –

+1

'protected' ist ein wichtiges Schlüsselwort, um zu verstehen, wenn Sie Dinge mit Vererbung machen. Hier ist ein anständiger Überblick: http://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html – aroth

+0

Okay, nochmals vielen Dank. –

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

Sie nicht initialisiert wird und die sounds bevölkern, bevor sie anrufen, gehen Sie wie folgt vor:
initialize und bevölkern sounds im constructor von PirateParrot und rufen dann Super 'speak Methode.

+0

Ich würde sagen "Sounds" ist initialisiert (sonst wäre eine NPE geworfen worden) - aber es ist einfach leer – hage

+0

durch initialisieren ich meinte es nicht leer machen ;-) (indem man es ausfüllt); – GingerHead

Verwandte Themen