Ce face enum cu câmpuri și metode
Constantele unui enum sunt obiecte, deci pot avea date proprii. Le dai valori între paranteze, după numele constantei, iar constructorul enum-ului le salvează în câmpuri final. Constructorul este implicit private: nimeni nu poate crea constante noi cu new.
Poți adăuga metode obișnuite (ca la orice clasă) și metode statice, de exemplu o căutare după cod. O metodă declarată abstract în enum trebuie implementată de fiecare constantă, în corpul ei propriu { ... }, astfel încât fiecare constantă să se comporte diferit.
Un enum poate implementa interfețe, dar nu poate extinde altă clasă (extinde deja java.lang.Enum). Lista de constante trebuie să fie primul lucru din corp și se termină cu ; când urmează câmpuri sau metode.
Exemple
Exemplul 1: Câmpuri, constructor și metode
Fiecare monedă are simbolul și cursul ei. Metoda inLei folosește câmpul constantei pe care a fost apelată.
enum Moneda {
RON("lei", 1.0),
EUR("€", 5.08),
USD("$", 4.37),
GBP("£", 5.86);
private final String simbol;
private final double curs;
Moneda(String simbol, double curs) {
this.simbol = simbol;
this.curs = curs;
}
double inLei(double suma) {
return suma * curs;
}
String formateaza(double suma) {
return String.format("%.2f %s", suma, simbol);
}
}
public class Main {
public static void main(String[] args) {
for (Moneda m : Moneda.values()) {
System.out.printf("%-8s = %s%n", m.formateaza(100), Moneda.RON.formateaza(m.inLei(100)));
}
}
}
Rezultat
100.00 lei = 100.00 lei
100.00 € = 508.00 lei
100.00 $ = 437.00 lei
100.00 £ = 586.00 lei
Exemplul 2: Comportament diferit pentru fiecare constantă
Metoda abstractă aplica este scrisă separat în corpul fiecărei constante. Câmpul semn ține simbolul afișat.
enum Operatie {
ADUNARE("+") {
@Override int aplica(int a, int b) { return a + b; }
},
SCADERE("-") {
@Override int aplica(int a, int b) { return a - b; }
},
INMULTIRE("*") {
@Override int aplica(int a, int b) { return a * b; }
};
final String semn;
Operatie(String semn) {
this.semn = semn;
}
abstract int aplica(int a, int b);
}
public class Main {
public static void main(String[] args) {
for (Operatie op : Operatie.values()) {
System.out.println("12 " + op.semn + " 4 = " + op.aplica(12, 4));
}
}
}
Rezultat
12 + 4 = 16
12 - 4 = 8
12 * 4 = 48
Exemplul 3: Căutare după cod și interfață implementată
Metoda statică dupaCod găsește județul după indicativ și returnează Optional. Enum-ul implementează interfața Descriptibil.
import java.util.Optional;
interface Descriptibil {
String descriere();
}
enum Judet implements Descriptibil {
IASI("IS", "Iași"),
CLUJ("CJ", "Cluj-Napoca"),
TIMIS("TM", "Timișoara"),
CONSTANTA("CT", "Constanța");
private final String cod;
private final String resedinta;
Judet(String cod, String resedinta) {
this.cod = cod;
this.resedinta = resedinta;
}
static Optional<Judet> dupaCod(String cod) {
for (Judet j : values()) {
if (j.cod.equalsIgnoreCase(cod)) {
return Optional.of(j);
}
}
return Optional.empty();
}
@Override
public String descriere() {
return "județul " + name() + " (" + cod + "), reședința " + resedinta;
}
}
public class Main {
public static void main(String[] args) {
for (String cod : new String[] {"tm", "CT", "XX"}) {
System.out.println(cod + " -> " + Judet.dupaCod(cod).map(Judet::descriere).orElse("necunoscut"));
}
}
}
Rezultat
tm -> județul TIMIS (TM), reședința Timișoara
CT -> județul CONSTANTA (CT), reședința Constanța
XX -> necunoscut
Greșeli frecvente
- Uiți
;după ultima constantă când urmează câmpuri: compilatorul dă erori greu de citit, de tipul',', '}', or ';' expected. - Faci câmpurile enum-ului modificabile (fără
final, cu setteri). Constantele sunt partajate de tot programul; o modificare se vede peste tot. - Pui
publicpe constructorul enum-ului:modifier public not allowed here. Constructorul este mereu privat.
Comenzi înrudite
enum: enum declară un tip cu un set fix de valori cu nume (zilele săptămânii, stările unei comenzi), verificat de compilator.Interfețe (interface, implements): O interfață (interface) descrie ce metode trebuie să aibă o clasă; clasa o promite cu implements și poate implementa mai multe interfețe.Clase abstracte (abstract): O clasă abstract nu poate fi instanțiată direct; poate avea metode abstracte, pe care subclasele concrete sunt obligate să le scrie.record: record declară o clasă imutabilă pentru date: constructorul, accesorii, equals, hashCode și toString sunt generați automat.