Rozszerzanie klasy Enum

0

Potrzebuję mieć enuma widocznego z wielu różnych klas, abym mógł w nich podać go (składową wyliczenia) jako argument do metod. Najodpowiedniejszym rozwiązaniem wydaje mi się, że jest po prostu stworzenie klasy dziedziczącej po Enum. Chciałem tak zrobić ale szybko zaczęły się schody - dokładnie już przy pierwszym zerknięciu w dokumentację :).

Widnieje tam taka definicja klasy:
public abstract class Enum<E extends Enum<E>>
Nie bardzo to rozumiem. Abstrakcyjna, generyczna klasa Enum przyjmuje parametr ograniczony przez tą samą klasę z tym samym parametrem ?? O co tu chodzi?

Oprócz tego oczywiście nie mam pojęcia jak będę miał w tej klasie zadeklarować swoje pola, żeby były dostępne na takiej samej zasadzie jak w zwykłych enumach.

Będę wdzięczny za pomoc w tym temacie.

0

Ok. Już wiem, że mogę rozwiązać swój problem tworząc statyczne stałe lub ewentualnie statycznego enuma, niemniej jednak chętnie dowiedziałbym się o co chodzi w tej definicji klasy Enum :)

2

Każde wyliczenie z automatu (i niejawnie) dziedziczy już po klasie Enum, która dla wyliczeń pełni rolę podobną jak Object dla wszystkich innych klas. Parametrem tej klasy bazowej jest właśnie to zdefiniowane wyliczenie dlatego ramka parametru sugeruje, że parametrem może być tylko ta sama klasa Enum lub to co po niej dziedziczy, czyli właśnie to konkretne wyliczenie. Ponieważ w Javie dziedziczenie jest tylko jednobazowe, więc konkretne wyliczenie nie może po niczym więcej dziedziczyć.

Za to dla odmiany można zmusić wyliczenia do implementowania jakiegoś interfejsu, więc w jednym interfejsie może mieścić się kilka wyliczeń i każde może zostać rzutowane na bazowy interfejs. W Javie do wersji 7 nie było to bardzo przydatne, ale w wersji 8 do interfejsu dochodzą metody domyślne oraz statyczne, więc daje to wyliczeniom sporo nowych możliwości. Ponieważ klasa wyliczenia jest nadal prawie normalną klasą, to można w niej zdefiniować różne (tylko) prywatne konstruktory, dzięki czemu elementy wyliczenia są traktowane jako wywołania takich konstruktorów zależnie od typu ich parametrów.
Każde utworzenie obiektu wyliczenia powoduje wyprodukowanie przez kompilator wywołania tego konstruktora:
protected Enum(String name, int ordinal) i nadanie mu jako argumentów nazwy elementu wyliczenia oraz numeru w kolejności występowania. To samo dzieje się nawet jeżeli w wyliczeniu zdefiniowano jakieś prywatne lub pakietowe konstruktory. Wtedy trzeba traktować ich wywołanie tak jakby w pierwszej linijce była instrukcja super(name.toString(), name.ordinal());. Co i tak jest bez znaczenia bo nie ma tego jak wykorzystać do swoich celów.
Krótko mówiąc: enum Xxx {...} == static class Xxx extended Enum<E extends Enum<E>> {...}. Z tego powodu wyliczeń nie można umieszczać w klasach wewnętrznych ponieważ nie mogą one mieć elementów statycznych, za to można je umieszczać w interfejsach bo tam dozwolone są tylko elementy statyczne.

Co do Twojego problemu, to zanim nie pojawiły się wyliczenie ich rolę pełniły właśnie interfejsy ze stałymi statycznymi. Ale było to niewygodne i podatne na błędy. Nic nie szkodzi, żeby stworzyć publicznego enuma bo jak już wiesz jest to normalna klasa. Jej elementy będą dostępne ze wszystkich innych klas, ale przed nazwą elementu będzie musiała się znaleźć nazwa tego wyliczenia z kropką.

1 użytkowników online, w tym zalogowanych: 0, gości: 1