Singletons, Enums und anonyme innere Klassen

8

Wie Sie vielleicht wissen, deklarieren einige Leute Singletons mit einer Enum of 1-Instanz, weil die JVM garantiert, dass es immer eine einzige Instanz ohne Parallelitätsprobleme geben wird ...

Also was ist mit einem Enum mit mehreren Instanzen? Können wir sagen, dass etwas wie ein Enum eine Art geordneter Satz von Singletons ist, die eine gemeinsame Schnittstelle teilen? Warum?

%Vor%

In diesem Code funktioniert das nicht: WITH_TAXES.getFormattedPrice (33f); Worin besteht das Interesse, eine öffentliche Methode zu deklarieren, wenn sie nicht ohne die gemeinsame Schnittstelle aufgerufen werden kann? Ich denke, deshalb sehe ich keine Syntax, um eine Schnittstelle nur für eine der Instanzen einer Enum deklarieren zu können.

Bearbeiten:

Es scheint, dass Enum-Instanzen eine besondere Art von anonymen Klassen sind. So verstehe ich, warum Sie diese Methode nicht aufrufen können.

Meine Frage ist irgendwie verwandt mit: Warum kann eine anonyme Klasse keine Schnittstelle implementieren (zusätzlich zur bereits implementierten Schnittstelle!)

Ich verstehe total, warum wir das tun können:

%Vor%

(getName ist hier keine Überschreibung)

Warum ich das nicht verstehe ist, warum wir das nicht mit anonymen Klassen tun können:

%Vor%

Oder etwas, das dasselbe bewirken würde. Denken Sie darüber nach: Wenn Sie keine anonymen Klassen verwenden, können Sie die Vehicle-Klasse unbedingt erweitern und dann diese Unterklasse dazu bringen, beliebige andere Schnittstellen zu implementieren ...

Ich bin mir ziemlich sicher, dass wir, wenn es möglich wäre, WITH_TAXES.getFormattedPrice (33f) in einer typsicheren Weise aufrufen könnten, da WITH_TAXES kein echter EnumPriceType wäre, sondern nur eine Unterklasse von EnumPriceType, mit einer eigenen Schnittstelle und durch Aufruf von WITH_TAXES.getFormattedPrice (33f) mit einem hartcodierten WITH_TAXES, wissen Sie bei der Kompilierung, welches EnumPriceType-Kind Sie aufrufen.

Meine Frage ist also: Gibt es Gründe, warum das nicht möglich ist? Oder es ist einfach noch nicht getan?

    
Sebastien Lorber 29.09.2011, 15:34
quelle

3 Antworten

11

Ihre enum ist äquivalent zu der folgenden normalen Klasse (in der Tat, das ist ziemlich genau das, was der Compiler daraus macht):

%Vor%

Die Methode getFormattedPrice() ist für den abstrakten Typ nicht verfügbar und kann daher nicht von der Hauptmethode aus aufgerufen werden. Überlegen Sie, was passieren würde, wenn die Hauptmethode für die Verwendung einer lokalen Variablen neu geschrieben wird:

%Vor%

Dies wird nicht kompiliert, da getFormattedPrice() für die Basisklasse nicht verfügbar ist. Da die WITH_TAXES -Instanz eine anonyme Unterklasse von EnumPriceType ist, gibt es keine Möglichkeit, die lokale Variable für einen Typ zu definieren, für den die Methode getFormattedPrice() sichtbar ist.

Dies ist, wie eine Meta-Beobachtung zeigt, ein Hauptunterschied zwischen stark typisierten Sprachen wie Java und "duck typed" -Sprachen wie Ruby. Ruby ruft gerne die getFormattedPrice() -Methode auf, wenn sie da ist, unabhängig davon, welcher Objekttyp in der foo -Variable enthalten ist.

Als weitere Meta-Beobachtung macht es nicht viel Sinn, wenn verschiedene Konstanten derselben enum unterschiedliche Mengenmethoden haben. Wenn Sie nicht alles, was Sie benötigen, als abstrakte (oder konkrete) Methoden auf den Basis-Enum-Typ setzen, verwenden Sie wahrscheinlich das falsche Werkzeug, um das Problem zu lösen.

    
Barend 29.09.2011, 15:45
quelle
2

Hinzufügen

%Vor%

außerhalb Die Überschreibungen als Standardimplementierung. (Neben der Erklärung von getPrice .) Und du bist gut zu gehen.

Sie können auch enums Schnittstellen implementieren, um zu definieren, was jeder implementieren muss.

    
Andrew Lazarus 29.09.2011 15:43
quelle
0
  

Also was ist mit einem Enum mit mehreren Instanzen?

Das gibt es nicht, und Ihr Beispiel zeigt es nicht. Sie haben eine Enum mit mehreren Werten. Sie sind alle Singletons.

    
EJP 29.09.2011 23:43
quelle