Java selbe enum mit verschiedenen Werten

8

Ich verwende eine Aufzählung, um mehrere Variationen zu definieren, die einem Produkt hinzugefügt werden können (benutzerdefiniertes Logo, Farben usw.). Jede Variation hat mehrere Optionen (ID, Beschreibung in zwei Sprachen, wo die Änderungen vorgenommen werden, Preis usw.). Es gibt Methoden, um die Variation weiter zu definieren (zum Beispiel welche Farbe verwendet werden soll) oder um bestimmte Optionen zu überschreiben. Ein Produkt kann entweder null, eine oder mehrere Variationen in einer ArrayList gespeichert haben. Außerdem kann eine bestimmte Variation mehr als einmal auf ein Produkt angewendet werden.

Solange ich eine Variation nur dann benutze, wenn alles in Ordnung ist. Aber wenn ich es mehr als einmal benutze, scheint es, dass alle die gleichen Optionen bekommen.

Beispielcode:

TestClass.java:

%Vor%

TestEnum.java:

%Vor%

Ist es möglich, mit einer Aufzählung zu tun, was ich vorhabe?

Wenn ja, was mache ich falsch? Vielleicht gibt es irgendeine Möglichkeit, eine Kopie eines Enums in einem bestimmten Zustand zu erstellen?

    
trik 24.11.2015, 20:24
quelle

5 Antworten

6

Nein, Enums sind nicht gut geeignet, um Objekte zu beschreiben, die ähnlich sind, aber unterschiedliche Zustände haben.

Enum-Konstanten sind statisch . Sie haben nicht zwei verschiedene Instanzen von TEST1 . Du hast nur einen. Die beiden Listeneinträge, die sich in Ihrem Beispiel auf TEST2 beziehen, beziehen sich auf dieselbe Instanz. Es ist keine Kopie, es ist eine zweite Referenz.

Um Instanzen zu haben, die ähnlich sind, aber leicht unterschiedliche Zustände haben, sollten Sie eine Klasse deklarieren, keine enum. Sie könnten eine Aufzählung verwenden, um die Art der Variation zu beschreiben (z. B. COLOR_VARIATION , CUSTOM_LOGO ). Sie könnten zwei verschiedene Klassen haben, die eine Klasse mit dem Namen Variation erweitern oder sie direkt verwenden - hängt davon ab, ob die Implementierungsdetails unterschiedlich sind. Sie verwenden jedoch new Variation(...) oder verwenden eine statische Factory-Methode, um eine neue Instanz von Variation zu erstellen, und dann kann jede Variation -Instanz eine andere Gruppe von Werten in ihren Feldern haben, selbst wenn sie beides sind gleicher "Variationstyp".

    
RealSkeptic 24.11.2015, 20:34
quelle
8

Nein, das können Sie nicht mit enums machen. Es gibt immer genau eine Instanz jedes Aufzählungswerts. Wenn Sie die Daten in der Enumeration ändern (z. B. mit einer Ihrer setOpn() -Methoden), wird sie global geändert, weil es nur eine gibt.

Es ist am besten, die Daten auf einer Enum unveränderlich zu machen. Dann können Sie für die Variablenoptionen jedem Objekt, das über Optionen verfügt, ein ArrayList zuweisen und ihm eines der Enums zuweisen.

Du könntest es so machen:

%Vor%     
Erick G. Hagstrom 24.11.2015 20:32
quelle
8

Die anderen Antworten auf dieser Seite sind wahrscheinlich alle korrekt, helfen Ihnen aber möglicherweise nicht wirklich bei der Lösung Ihres Problems.

Versuchen Sie anstelle einer Aufzählung eine einfache alte Klasse zu implementieren, aber fügen Sie eine Methode clone() hinzu. Anschließend können Sie einige "Standard" -Instanzen der Klasse erstellen, die jeweils eine Standardproduktkonfiguration darstellen. Wenn ein Benutzer eine bestimmte Produktkonfiguration auswählt, rufen Sie clone() für das Master-Objekt auf, dann können Sie einfach reguläre Setter verwenden, um das Objekt von hier aus zu ändern.

Sehen Sie sich das Entwurfsmuster für Prototypen an. Die ganze Idee besteht darin, diese "Master" -Objekte zu verwenden, um neue Kopien zu erstellen, die dann geändert werden können. Ich denke, das ist vielleicht ein bisschen mehr, wonach Sie suchen. Ссылка

    
David Loewy 24.11.2015 20:39
quelle
2

Es gibt nur eine Instanz jedes Aufzählungswerts. Stellen Sie sich diese als globale Variablen vor, die vom Compiler erzwungen werden.

%Vor%

Erstens macht das explizite Nullen der enumVar -Referenz nichts. Zweitens verweisen Sie, wenn Sie TestEnum.TEST2 referenzieren, auf denselben Wert in beiden Blöcken - was bedeutet, dass Ihre späteren Aufrufe von setOp die vorherigen Werte überschreiben.

    
Tom G 24.11.2015 20:33
quelle
1

Normalerweise ist ein Enum per definitionem invariant. Indem Sie Setter zu Ihrem Enum hinzufügen, machen Sie es zur Variante.

Was Ihre Frage angeht, liegt das daran, dass Sie in Ihrem Array dieselbe Referenz auf TEST2 haben. Da es sich um eine Referenz handelt, sind das zweite und das dritte Element exakt gleich. Wenn Sie also eines der Elemente TEST2 ändern, spiegelt die andere Referenz die Änderung wider.

Um dies zu testen, können Sie die Zuweisungszeilen ( enumVar.setOp1 ) vom dritten zum zweiten Element wechseln und Sie werden das gleiche Verhalten sehen.

Es ist so, als ob Sie das Enum zu einem Objekt transformiert hätten.

    
JFPicard 24.11.2015 20:34
quelle

Tags und Links