2010-08-06 19 views
5

Ich mache astrophysikalische Forschung. Ich habe ein Paket geschrieben, das die Klassen Star, Band und Datfile enthält. Ich habe auch den aufgezählten Typ von BandName. Jeder Stern enthält mehrere Bänder, jedes Band enthält mehrere Datendateien.Enumeration Vererbung in Java?

Ich habe Beobachtungsdaten für mehrere Galaxien. Für jede von diesen mache ich eine StarDatabase-Klasse (eine HashMap of Stars) und eine Main-Klasse.

Das Problem, das ich habe, ist mit dem aufgezählten Typ von BandName. Bisher waren alle Daten, die ich verwendet habe, in den I- und V-Bändern. Jetzt habe ich Daten in J-, H- und K-Bändern. Wenn ich einfach J, H und K zu BandName hinzufüge, sind alle meine Schleifen, die über alle Elemente in BandName iterieren und etwas tun, jetzt unterbrochen.

Irgendwelche Ideen?

Bearbeiten: Um mein Problem zusammenzufassen, möchte ich, dass jedes Paket eine eigene BandName-Enum hat, die es durchlaufen kann. Dies funktioniert jedoch nicht, da die Methoden im Star-Paket Objekte vom Typ Star.BandName erwarten und Objekte vom Typ IndividualPackage.BandName bereitstellen.

+0

Warum wiederholst du die BandNames? – ILMTitan

+0

Für den Fall, dass ein neues Band hinzugefügt werden muss, muss nicht überall, wo ich einen BandName verwende, aktualisiert werden. – rhombidodecahedron

+0

Was entsprechen die Pakete? Das heißt, warum bilden Sie diese Klassen überhaupt ab? –

Antwort

18

Sie können eine Enumeration nicht von einer anderen Enumeration erben, obwohl Ihre Enumeration eine Schnittstelle implementieren kann. Das technische Problem (dass alle Aufzählungen implizit java.lang.Enum verlängern, so können sie eine andere Klasse nicht erweitern, nur zusätzliche Schnittstellen implementieren) ist kein Zufall:

Zum größten Teil, Erweiterbarkeit von Aufzählungen erweist sich schlecht sein Idee. Es ist verwirrend, dass Elemente eines Erweiterungstyps Instanzen des Basistyps sind und nicht umgekehrt. Es gibt keine gute Möglichkeit, über alle Elemente eines Basistyps und seiner Erweiterung aufzuzählen. Schließlich würde die Erweiterbarkeit viele Aspekte des Designs und der Implementierung erschweren.

Von Effective Java 2nd Edition, Punkt 34.

Allerdings habe ich nicht vollständig verstehen Ihr Problem: nicht verwendet, um Sie values() für durch Ihre Enum Iterieren? Dann sollten Sie sich keine Gedanken darüber machen, Ihr Enum mit neuen Werten zu erweitern.

Bitte spezifizieren Sie deutlicher, was "gebrochen" bedeuten soll.

Update:, so dass Sie verschiedene Sätze von Bändern für verschiedene Arten von Sternen haben müssen - diese unterschiedliche Aufzählungen implementiert werden kann, eine gemeinsame Schnittstelle erstreckt, zB:

interface Band { 
    String getName(); 
    void doStuff(); 
    ... 
} 

enum BandsVI implements Band { 
    V, I; 
    public String getName() { return toString(); } 
    public void doStuff() { /* do stuff as appropriate for these bands */ } 
    ... 
} 

enum BandsJHK implements Band { 
    J, H, K; 
    public String getName() { return toString(); } 
    public void doStuff() { /* do stuff as appropriate for these bands */ } 
    ... 
} 

Und Sie können diese nutzen, indem Machen Sie Ihre Star-Klasse generisch:

Dies funktioniert gut, wenn die Bänder in verschiedenen Gruppen organisiert sind. Wenn es Sterne mit gemischten Bandgruppen sind jedoch könnten Sie einen alternativen Ansatz bevorzugen:

class Star { 
    private List<? extends Band> bandTypes; 
    public Star(List<? extends Band> bandTypes) { this.bandTypes = bandTypes; } 
    public void printBandNames() { 
    for (Band b : bandTypes) 
     System.out.println(b.getName()); 
    } 
    ... 
} 

... 
Star star1 = new Star(Arrays.asList(BandsVI.values())); 
Star star3 = new Star(Arrays.asList(new Band[]{BandsVI.V, BandsVI.I, BandsJHK.K})); 
... 

Auf diese Weise können Sie Stern mit einer beliebigen Mischung aus Bands einzurichten. Auf diese Weise können Sie EnumSet oder EnumMap auf den Bändern nicht verwenden.

+0

Zum Beispiel durchläuft jedes Star-Objekt durch BandName.values ​​() und fügt ein neues Band hinzu mit dem genannten Wert. Dann sucht dieses Band im Verzeichnis/value nach den Datendateien. Dann erstellt die GUI ein neues BandRadioButton aus jedem Band in BandName.values ​​() ... usw. und so weiter. – rhombidodecahedron

+0

@Earl, ich verstehe immer noch nicht, wo das Problem liegt: Ist die Datendatei für die neuen Bänder nicht vorhanden, oder wird die GUI durcheinander gebracht oder ...? –

+0

Die GUI wird tatsächlich durcheinander gebracht. Die Sterne, die sich mit den V- und I-Bändern beschäftigen, sollten überhaupt nicht mit dem J, H oder K interagieren. Ich möchte es durch die Werte durchlaufen (anstatt sie explizit zu benennen) für den Fall, dass eine neue Band _does_ hinzugefügt werden muss. – rhombidodecahedron

0

Alle Enums erweitern implizit java.lang.Enum. Da Java keine Mehrfachvererbung unterstützt, kann eine Enumeration nichts anderes erweitern.- http://download.oracle.com/javase/tutorial/java/javaOO/enum.html

+0

Ich weiß das. Daher die Frage. – rhombidodecahedron

+2

@Earl, er hatte keine Möglichkeit zu wissen, dass du das wusstest. Es ist schwierig für uns unmöglich, Ihnen gute Antworten zu geben, wenn Sie uns nicht genügend Informationen über das Problem geben. –

+0

Ich entschuldige mich. Das sollte nicht unhöflich klingen. – rhombidodecahedron

0

Dies ist, was ich tun würde (Pseudo-Code):

class Band 
{ 
    String name; 
}; 
static Band J("J"); 
static Band K("K"); 

static ArrayList<Band> JK; 
static ArrayList<Band> IHL; 

class Star 
{ 
    Star(ArrayList<Band> bands) 
} 

Auf diese Weise können Bänder nur um die Schaffung von mehr Band Objekte hinzufügen können. Jeder Start hat die Liste der Bänder, die er verwendet, so dass er über alle diese iterieren kann.