Abstraktit metodit enumeissa
Vakiokohtainen toiminta.
Abstraktit metodit enumeissa on ilmainen Java Academy-oppitunti CoddyKitissä. Tämä on oppitunti 2/4. Voit lukea koko oppitunnin alta ilmaiseksi ja harjoitella sen jälkeen käytännössä selaimessa sisäänrakennetulla koodieditorilla ja ympäri vuorokauden käytettävissä olevan tekoälytuutorin avulla. Oppitunti kuuluu Java Academy-oppimispolkuun, ja edistymisesi synkronoituu verkon ja CoddyKit-sovelluksen välillä. Java Academy-kurssilla on yhteensä 4 oppituntia.
Vakiokohtainen toiminta
Joskus jokainen enum-vakio tarvitsee erilaista toimintaa, ei vain erilaisia tietoja.
Javassa enum-tyypille voi määrittää abstraktin metodin ja ylikirjoittaa sen jokaisen vakion kohdalla. Tätä kutsutaan vakiokohtaisen metodirungon malliksi.
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));
}
}Näin se toimii
Jokaisesta vakioista, jolla on oma runkonsa, tulee enum-tyypin nimetön aliluokka.
Abstrakti metodi pakottaa jokaisen vakion tarjoamaan toteutuksen, joten kääntäjä varmistaa kattavuuden.
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));
}
}Täysi laskin
Neljä aritmeettista operaatiota vakioina, joista jokaisella on oma apply-metodin toteutuksensa.
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));
}
}
}Kenttien ja toiminnan yhdistäminen
Voitte yhdistää kentän, kuten symbolin, vakiokohtaiseen toimintaan. Kenttä nimeää operaation ja metodi suorittaa sen.
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));
}
}Miksei switch-lauseketta?
Voisitte toteuttaa apply-metodin yhdellä vakioon kohdistuvalla switch-lausekkeella, mutta abstraktiin metodiin perustuva ratkaisu on turvallisempi.
Jos lisäätte myöhemmin uuden vakion, kääntäjä pakottaa teidät antamaan sille oman toteutuksensa. Switch-lauseke voisi ohittaa uuden tapauksen huomaamatta.
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));
}
}Konkreettiset metodit abstraktien rinnalla
Enum-tyypissä voi yhdistää abstrakteja ja konkreettisia metodeja. Yhteinen logiikka sijoitetaan konkreettiseen metodiin ja vaihteleva logiikka jätetään abstraktiksi.
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));
}
}Strategia-enumit
Yksi kehitysaskel on strategia-enum: vakiot delegoivat sisäkkäiselle strategia-enumille sen sijaan, että ylikirjoittaisivat metodin suoraan.
Tämä on hyödyllistä, kun useat vakiot jakavat saman toiminnan. Tässä esimerkissä arkipäivien ja viikonloppujen palkkalaskenta eroaa toisistaan.
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));
}
}Enum-tyyppi rajapinnalla ja vakiokohtaisilla toteutuksilla
Yhdistämällä rajapinnan ja vakiokohtaiset toteutukset saatte mahdollisimman monipuolisen polymorfismin.
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());
}
}Kenttien käyttö toteutuksista
Vakiokohtainen toteutus voi lukea oman vakionsa kenttiä, koska kukin toteutus suoritetaan kyseisen instanssin kontekstissa.
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));
}
}Oletustoteutus ja ylikirjoitus
Voitte antaa enum-tyypin rungossa konkreettisen oletustoteutuksen ja ylikirjoittaa sen vain niiden vakioiden kohdalla, jotka poikkeavat oletuksesta.
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"));
}
}Pieni tilakone
Vakiokohtainen toiminta on parhaimmillaan tilakoneissa: jokainen tila tuntee oman siirtymänsä.
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);
}
}Pikatesti
Testatkaa ymmärrystänne enum-tyyppien abstrakteista metodeista.
Kertaus
Opitte vakiokohtaisesta toiminnasta:
- Määritä abstrakti metodi ja ylikirjoita se jokaisen vakion rungossa.
- Jokaisesta vakiosta tulee nimetön aliluokka.
- Kääntäjä valvoo kattavuutta, joten ratkaisu on switch-lauseketta varmempi.
- Monipuolisissa enum-tyypeissä voi yhdistää kenttiä, konkreettisia oletustoteutuksia ja rajapintoja.
Seuraavaksi käsitellään suorituskykyistä EnumSet-tyyppiä.
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());
}
}Opi Java tekoälytuutorin avulla — ilmaiseksi
Kirjoita ja suorita oikeaa koodia selaimessa, saa välitöntä apua tekoälytuutorilta ympäri vuorokauden ja jatka siitä, mihin jäit, verkossa tai sovelluksessa.
- Kurssit
- 104
- Oppitunnit
- 374
Usein kysytyt kysymykset
Onko oppitunti ”Abstraktit metodit enumeissa” ilmainen?
Kyllä – oppitunnin ”Abstraktit metodit enumeissa” koko tekstin voi lukea täällä verkossa ilmaiseksi. Jos haluat harjoitella interaktiivisesti sisäänrakennetulla koodieditorilla ja ympäri vuorokauden käytettävissä olevan tekoälytuutorin avulla sekä avata koko Java Academy-kurssin, päivitä CoddyKit PROhon. Java Academy-kurssilla on yhteensä 4 oppituntia.
Mitä opin oppitunnilla ”Abstraktit metodit enumeissa”?
Vakiokohtainen toiminta. Harjoittelet Java Academy-aihetta koodilla, jonka suoritat suoraan selaimessa. Ympäri vuorokauden käytettävissä oleva tekoälytuutori vastaa kysymyksiisi oppitunnin aikana.
Tarvitsenko kokemusta aloittaakseni Java Academy-opiskelun?
Aiempi kokemus ei ole tarpeen. CoddyKitin Java Academy-oppimispolku sopii vasta-alkajista edistyneisiin, joten voit aloittaa tästä tai alusta ja edetä omaan tahtiisi. Tämä on oppitunti 2/4.
Kuinka kauan ”Abstraktit metodit enumeissa”-oppitunnin suorittaminen kestää?
Useimmat CoddyKitin oppitunnit kestävät noin 5–10 minuuttia. Jokainen oppitunti on lyhyt ja interaktiivinen, joten edistyt tasaisesti ja voit jatkaa siitä, mihin jäit – sekä verkossa että sovelluksessa.
Voinko kirjoittaa ja suorittaa koodia tällä Java Academy-oppitunnilla?
Kyllä. Jokainen Java Academy-oppitunti sisältää sisäänrakennetun koodieditorin, joten voit kirjoittaa ja suorittaa oikeaa koodia suoraan selaimessa ja saada välitöntä palautetta tekoälyltä – paikallista asennusta ei tarvita.
Kaikki tämän kurssin oppitunnit
- Enumit kenttien ja metodien kanssa
- Abstraktit metodit enumeissa
- EnumSet
- EnumMap