Abstrakta metoder i enumtyper
Beteende per konstant.
Abstrakta metoder i enumtyper är en gratis lektion i Java Academy på CoddyKit. Detta är lektion 2 av 4. Ni kan läsa hela lektionen gratis nedan och sedan öva praktiskt i webbläsaren med en inbyggd kodredigerare och en AI-handledare som är tillgänglig dygnet runt. Den ingår i lärvägen för Java Academy, och Era framsteg synkroniseras mellan webben och CoddyKit-appen. Kursen i Java Academy innehåller totalt 4 lektioner.
Konstant-specifikt beteende
Ibland behöver varje enumkonstant olika beteende, inte bara olika data.
Java låter dig deklarera en abstrakt metod i enumtypen och åsidosätta den för varje konstant. Det här är mönstret med konstant-specifika metodkroppar.
public class Main {
enum Operation {
PLUS { public int apply(int a, int b) { return a + b; } },
MINUS { public int apply(int a, int b) { return a - b; } };
public abstract int apply(int a, int b);
}
public static void main(String[] args) {
System.out.println(Operation.PLUS.apply(3, 4));
System.out.println(Operation.MINUS.apply(10, 6));
}
}Så fungerar det
Varje konstant med en metodkropp blir en anonym underklass av enumtypen.
Den abstrakta metoden tvingar varje konstant att tillhandahålla en implementation, så kompilatorn garanterar att alla fall är implementerade.
public class Main {
enum Operation {
TIMES { public int apply(int a, int b) { return a * b; } };
public abstract int apply(int a, int b);
}
public static void main(String[] args) {
// The constant is an instance of a generated subclass
System.out.println(Operation.TIMES.getClass().getSimpleName().isEmpty()
? "anonymous subclass" : Operation.TIMES.apply(6, 7));
}
}En komplett kalkylator
De fyra räkneoperationerna som konstanter, var och en med sin egen apply-metodkropp.
public class Main {
enum Operation {
PLUS { public double apply(double a, double b) { return a + b; } },
MINUS { public double apply(double a, double b) { return a - b; } },
TIMES { public double apply(double a, double b) { return a * b; } },
DIVIDE{ public double apply(double a, double b) { return a / b; } };
public abstract double apply(double a, double b);
}
public static void main(String[] args) {
double x = 6, y = 3;
for (Operation op : Operation.values()) {
System.out.printf("%s -> %.1f%n", op, op.apply(x, y));
}
}
}Kombinera fält och beteende
Du kan kombinera ett fält (en symbol) med konstant-specifikt beteende. Fältet beskriver operationen; metoden utför den.
public class Main {
enum Operation {
PLUS("+") { public double apply(double a, double b) { return a + b; } },
MINUS("-") { public double apply(double a, double b) { return a - b; } };
private final String symbol;
Operation(String symbol) { this.symbol = symbol; }
public abstract double apply(double a, double b);
@Override public String toString() { return symbol; }
}
public static void main(String[] args) {
Operation op = Operation.PLUS;
System.out.println("2 " + op + " 3 = " + op.apply(2, 3));
}
}Varför inte en switch?
Du skulle kunna implementera apply med en enda switch över konstanten, men metoden med en abstrakt metod är säkrare.
Om du lägger till en konstant senare tvingar kompilatorn dig att ange dess metodkropp. En switch kan däremot tyst missa det nya fallet.
public class Main {
enum Op {
SQUARE { public int apply(int n) { return n * n; } },
CUBE { public int apply(int n) { return n * n * n; } };
public abstract int apply(int n);
}
public static void main(String[] args) {
System.out.println(Op.SQUARE.apply(5));
System.out.println(Op.CUBE.apply(3));
}
}Konkreta metoder tillsammans med abstrakta
En enumtyp kan kombinera abstrakta och konkreta metoder. Gemensam logik placeras i en konkret metod; varierande logik förblir abstrakt.
public class Main {
enum Shape {
CIRCLE { public double area(double x) { return Math.PI * x * x; } },
SQUARE { public double area(double x) { return x * x; } };
public abstract double area(double x);
public String report(double x) { return this + " area = " + area(x); }
}
public static void main(String[] args) {
System.out.println(Shape.CIRCLE.report(2));
}
}Strategienumtyper
En vidareutveckling är en strategienumtyp: konstanterna delegerar till en nästlad strategienumtyp i stället för att åsidosätta metoden direkt.
Detta är användbart när flera konstanter delar beteende. Här skiljer sig vardagar och helger åt i löneberäkningen.
public class Main {
enum PayType {
WEEKDAY { int overtime(int mins) { return mins; } },
WEEKEND { int overtime(int mins) { return mins * 2; } };
abstract int overtime(int mins);
int pay(int mins) { return mins + overtime(Math.max(0, mins - 480)); }
}
public static void main(String[] args) {
System.out.println("Weekend pay: " + PayType.WEEKEND.pay(540));
}
}Enumtyp med gränssnitt och metodkroppar
Kombinera ett gränssnitt med konstant-specifika metodkroppar för maximal polymorfism.
public class Main {
interface Command { String run(); }
enum Action implements Command {
START { public String run() { return "starting..."; } },
STOP { public String run() { return "stopping..."; } };
}
public static void main(String[] args) {
for (Action a : Action.values()) System.out.println(a.run());
}
}Åtkomst till fält från metodkroppar
En konstant-specifik metodkropp kan läsa konstantens egna fält, eftersom varje metodkropp körs i kontexten för den instansen.
public class Main {
enum Tax {
STANDARD(0.20) { double apply(double amt) { return amt * (1 + rate); } },
REDUCED(0.05) { double apply(double amt) { return amt * (1 + rate); } };
protected final double rate;
Tax(double rate) { this.rate = rate; }
abstract double apply(double amt);
}
public static void main(String[] args) {
System.out.printf("%.2f%n", Tax.STANDARD.apply(100));
}
}Standard, sedan åsidosättning
Du kan ge en konkret standardimplementation i enumtypen och åsidosätta den endast för de konstanter som skiljer sig.
public class Main {
enum Notifier {
EMAIL,
SMS { String send(String m) { return "SMS: " + m; } };
String send(String m) { return "EMAIL: " + m; }
}
public static void main(String[] args) {
System.out.println(Notifier.EMAIL.send("hi"));
System.out.println(Notifier.SMS.send("hi"));
}
}En liten tillståndsmaskin
Konstant-specifikt beteende kommer till sin rätt i tillståndsmaskiner: varje tillstånd känner till sin egen övergång.
public class Main {
enum State {
IDLE { State next() { return RUNNING; } },
RUNNING { State next() { return DONE; } },
DONE { State next() { return DONE; } };
abstract State next();
}
public static void main(String[] args) {
State s = State.IDLE;
for (int i = 0; i < 3; i++) { System.out.println(s); s = s.next(); }
System.out.println(s);
}
}Snabbtest
Testa dina kunskaper om abstrakta enummetoder.
Sammanfattning
Du har lärt dig konstant-specifikt beteende:
- Deklarera en abstrakt metod och åsidosätt den i varje konstantkropp.
- Varje konstant blir en anonym underklass.
- Kompilatorn tvingar fram fullständighet, vilket är säkrare än en switch.
- Kombinera fält, konkreta standardimplementationer och gränssnitt för innehållsrika enumtyper.
Därefter: den högpresterande EnumSet.
public class Main {
enum E { A { int v() { return 1; } }; abstract int v(); }
public static void main(String[] args) {
System.out.println("Abstract enum recap: " + E.A.v());
}
}Lär dig Java med en AI-lärare – gratis
Skriv och kör riktig kod i webbläsaren, få omedelbar hjälp av en AI-lärare dygnet runt och fortsätt där du slutade – på webben eller i appen.
- Kurser
- 104
- Lektioner
- 374
Vanliga frågor
Är lektionen ”Abstrakta metoder i enumtyper” gratis?
Ja – hela texten till ”Abstrakta metoder i enumtyper” kan läsas gratis här på webben. Om Ni vill öva interaktivt med en inbyggd kodredigerare och en AI-handledare som är tillgänglig dygnet runt och låsa upp resten av kursen i Java Academy, kan Ni uppgradera till CoddyKit PRO. Kursen i Java Academy innehåller totalt 4 lektioner.
Vad lär jag mig i ”Abstrakta metoder i enumtyper”?
Beteende per konstant. Ni övar på Java Academy med praktisk kod som körs direkt i webbläsaren, medan en AI-handledare som är tillgänglig dygnet runt svarar på Era frågor under lektionen.
Behöver jag någon erfarenhet för att börja lära mig Java Academy?
Du behöver inga förkunskaper. Utbildningen i Java Academy på CoddyKit är upplagd för allt från nybörjare till avancerade elever, så att du kan börja här eller från början och gå fram i din egen takt. Detta är lektion 2 av 4.
Hur lång tid tar lektionen ”Abstrakta metoder i enumtyper”?
De flesta CoddyKit-lektioner tar cirka 5–10 minuter. Varje lektion är kort och interaktiv, så att du gör stadiga framsteg och kan fortsätta precis där du slutade – på webben eller i appen.
Kan jag skriva och köra kod i den här Java Academy-lektionen?
Ja. Varje Java Academy-lektion innehåller en inbyggd kodredigerare, så att du kan skriva och köra riktig kod direkt i webbläsaren och få omedelbar AI-feedback – utan lokal installation.
Alla lektioner i den här kursen
- Enum med fält och metoder
- Abstrakta metoder i enumtyper
- EnumSet
- EnumMap