Enum to typ wyliczeniowy (z ang. enumerated type). Wygląda jak klasa, tyle że zamiast słowa
class
piszemy
enum. Enum zwykle zawiera listę nazwanych stałych ("zwykle", bo może mieć na przykład tylko jedną stałą).
Podstawową różnicą w stosunku do klas jest to, że instancja stałej jest tworzona
NIE przez użycie słowa kluczowego
new, ale przez zwykłe odwołanie się do stałej.
Appa Notka.
Technicznie rzecz ujmując, można powiedzieć, że jeśli na bazie klas powstają obiekty, to owe instancje stałych też są obiektami
(enumy mają konstruktory, pola i metody, a nawet mogą implementować interfejsy).
Natomiast w oficjalnej dokumentacji Javy (co ciekawe), nie są one jawnie nazwane obiektami. Co prawda znajdują się w sekcji
przedstawiającej klasy i obiekty, ale w konkretnym rozdziale Enum Types nie są tak nazywane (dokumentacja mówi o nich po prostu jako o stałych).
Niemniej ze względu na to, iż wywodzą się z klas
i posiadają większość ich cech, określenia obiekt będziemy używać umownie.
Na przykład w aplikacji przechowującej
dokumenty, możemy za pomocą
enuma określić nazwy typów dokumentów.
W ten sposób ustalamy, że tylko takie wartości mogą zostać zdefiniowane jako typ dokumentu.
Do takiego enuma odwołamy się w ten sposób:
Wynik wykonania kodu:
Na powyższym przykładzie dobrze widać, że typ
Enum zachowuje się podobnie jak klasa.
Jednak w przeciwieństwie do klas, obiektu nie tworzymy tutaj przez użycie słowa kluczowego
new (może to jest powód unikania określenia obiekt w dokumentacji),
tylko przez odwołanie się do stałej:
W taki sposób
powstaje obiekt typu Enum (a w naszym przykładzie także typu
DocumentType).
Możemy przekazać go jako parametr metody.
Tak samo możemy wykonać porównanie za pomocą metody
equals. W tym momencie warto sobie odpowiedzieć na pytanie, z czego właściwie wynika to podobieństwo dla klas?
Skąd się bierze enum ?
Enum działa podobnie jak klasa, bo i też wywodzi się z klasy. Precyzyjniej mówiąc, wywodzi się (dziedziczy niejawnie) z klasy abstrakcyjnej o nazwie
Enum:
Tak więc enum może mieć konstruktory, metody i pola. Istotne jest jednak to, że programista nie używa
konstruktora do stworzenia enuma. Tworzenie odbywa się w sposób pokazany wcześniej, czyli przez odwołanie się do stałej. Ale to już wiemy. To, co jeszcze jest ważne, to charakterystyka
tej stałej. Stała jest publiczna, statyczna oraz finalna.
Metoda values
Metoda
values umożliwia zwrócenie wszystkich wartości danego enuma. Może nie jest idealna (zwraca tablicę),
ale za to przydaje się, gdy chcemy wykonać jakieś operacje kolejno dla każdej z wartości:
Wynik wykonania kodu:
Metoda valueOf
Metoda
valueOf zwraca stałą z enuma dla wartości podanej w parametrze:
Wynik wykonania kodu:
Tutaj dobrze widać to, że obiekty są zarówno typu
Enum, jak i
DocumentType.
Konstruktor i metody
Teraz pytanie, co będzie, jeśli do naszego enuma dodamy
pole, które ustawimy z poziomu konstruktora?
W takiej sytuacji nasz enum przestanie się kompilować (żółty kolor na zdjęciu wynika z podpowiedzi IntelliJ - można go tutaj pominąć):
Dzieje się tak, ponieważ wprowadzając konstruktor parametrowy, wyłączyliśmy widoczność konstruktora domyślnego (bezparametrowego).
Można powiedzieć, że przykład ze zdjęcia doskonale obrazuje to, jak działają enumy.
Widać, że samo zdefiniowanie wartości jest rozumiane jako chęć stworzenia obiektu. To trochę tak, jakbyśmy tam mieli napisane
new INVOICE(),
new CONTRACT() itd.
Tylko że tak wygląda tworzenie obiektów z regularnych klas. W przypadku enumów wystarczy samo zdefiniowanie stałej wartości.
Tak więc, skoro mamy tutaj do czynienia z konstruktorem parametrowym, to nie pozostaje nam nic innego, jak podać wartość
tego parametru. Jako że parametr określiliśmy w postaci typu
int, przekazujemy wartość w postaci liczby.
Metodę
getId wywołujemy normalnie tak, jak na regularnym obiekcie:
Wynik wykonania kodu:
Wiele konstruktorów i wiele metod
Oczywiście, jeśli tylko potrzebujemy, możemy stworzyć kilka konstruktorów z różnymi parametrami (tak jak w przypadku typowych klas).
Poniższy przykład przedstawia kilka różnych możliwości:
Metody - ponownie - wywołujemy normalnie, jak na każdym obiekcie:
Wynik wykonania kodu:
Powyższe przykłady (szczególnie ostatni) bardzo dobrze obrazują ideę enumów. Definiując stałe, tak naprawdę od razu
mówimy kompilatorowi, jakie obiekty ma stworzyć (stąd kompilator buntuje się, jeśli nie dostarczymy wymaganego konstruktora).
W momencie, gdy odwołujemy się do stałej, obiekt zostaje stworzony i jest on dokładnie tego typu co nasz enum.
Enum i instrukcja switch
Na koniec przykład, w jaki sposób można użyć enuma w ramach instrukcji
switch:
Wynik wykonania kodu:
Autor: Jarek Klimas
Data: 03 stycznia 2024
Labele: Backend, Podstawowy, Java
Czy informacje, które otrzymałeś, były pomocne?
Jeśli tak, zapraszam Cię do podarowania mi kawy.
Masz pytanie dotyczące prezentowanego materiału?
Coś jest dla Ciebie niejasne i Twoje wątpliwości przeszkadzają Ci w pełnym zrozumieniu treści?
Napisz do nas maila, a my chętnie znajdziemy odpowiednie rozwiązanie.
Najciekawsze pytania wraz z odpowiedziami będziemy publikować pod rozdziałem.
Nie czekaj. Naucz się programować jeszcze lepiej.