Enums und Vererbung

Ich weiß, dass das direkt nicht geht. Wie löst ihr soetwas?

Ich fände es praktisch, wenn ich in einem Projekt A, das mehrere andere verwenden, eine Art Grundstock an Aufzählungselementen anbieten könnte, der dann von anderen Projekten, die dieses Projekt A verwenden, erweitert werden könnte.

Ich hab leider gerade kein konkretes Beispiel, es war mir irgendwann mal begegnet und ich hab dann darauf verzichtet, diese Elemente zu erweitern.

Vermutlich steht das dem eigentlichen Sinn eines Aufzählungstyps entgegen, der eine feste Menge an Werten vorgibt, die er annehmen kann. Praktisch wäre es aber durchaus.

Frage: Gibt es da ein empfehlenswertes Standard-Vorgehen?

Korrekt. Dadurch gewinnt man ja den Vorteil der Type/Werte Sicherheit.

Eine „offene“ und vererbare Menge an Aufzählungselementen birgt entsprechende Risiken. Eine Best Practise kenne ich jetzt nicht, aber letztendlich wird es wohl irgendwie auf die Interface/Klasse mit static final .... Variante hinauslaufen. Mit den Risiken, dass man den Wertebereich nicht einschränken kann (aber das will man ja auch und geht es bewusst ein) und dass bei der Vererbung Werte/Elemente verdeckt werden können.
Wenn man für die Elemente eigene Objekte statt int, String usw. nimmt, kann man den möglichen Wertebereich etwas im Zaum halten.

Mir fiele keine ein, wo die Enum-Eigenschaften (switch-barkeit, Singleton-Charakter…) erhalten blieben. Das schwierige bei sowas ist, dass zwei Projekte die gleiche “Konstante” als “Erweiterung” definieren könnten, und damit Konflikte entstehen…

[quote=_Michael]Eine „offene“ und vererbare Menge an Aufzählungselementen birgt entsprechende Risiken. Eine Best Practise kenne ich jetzt nicht, aber letztendlich wird es wohl irgendwie auf die Interface/Klasse mit static final … Variante hinauslaufen. Mit den Risiken, dass man den Wertebereich nicht einschränken kann (aber das will man ja auch und geht es bewusst ein) und dass bei der Vererbung Werte/Elemente verdeckt werden können.
Wenn man für die Elemente eigene Objekte statt int, String usw. nimmt, kann man den möglichen Wertebereich etwas im Zaum halten.[/quote]

Ja. Ich hab mich bei meinem Anwendungsfall dagegen entschieden und das Problem anders gelöst. Die Risiken einzugehen war in dem Fall weniger elegant als das Vererben zu umgehen und das ganze anderweitig zu lösen.

Das stimmt, das klingt in der Tat eklig.

Hmm, mir fällt auch gerade kein konkretes Beispiel ein. Ein möglicher Workaround wäre ein (evtl. generisches) Interface, dass die Enums implementieren könnten. So hätte man wenigstens einen gemeinsamen Supertypen. switch-cases sind damit freilich nicht möglich. Aber in bestimmten Fällen mag das reichen.

… Ich sollte öfter Reload klicken, bevor ich antworte…

Das klingt aber auch nicht wirklich verlockend.

Ich hatte an Stellen, wo so etwas ähnliches hilfreich gewesen wäre, mal sowas gemacht wie

final class Attribute
{
    public static final Attribute FIRST = create("First");
    public static final Attribute SECOND = create("Second");
    ...

    private Attribute(String name) { ... } // Privater Konstruktor

    // Methode, um Instanzen zu erstellen: Kann gewisse
    // Konsistenzprüfungen machen (z.B. prüfen, dass es
    // kein Attribut doppelt gibt...)
    public static Attribute create(String name) { ... }   
}

aber das ist natürlich nur ein schwacher Ersatz (es kann ggf. Konflikte erkennen, aber sie nicht verhindern - zumindest nicht rein technisch, sondern nur durch Konventionen, und … dann kommen diese anti-autoritär erzogenen Hippies, und wir wissen ja, was die von „Konventionen“ halten :smiley: )