เมธอดนามธรรมในอีนัม
พฤติกรรมเฉพาะแต่ละค่าคงที่
เมธอดนามธรรมในอีนัม เป็นบทเรียน Java Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Java Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Java Academy มีบทเรียนทั้งหมด 4 บทเรียน
พฤติกรรมเฉพาะค่าคงที่
บางครั้งค่าคงที่แต่ละตัวของอีนัมต้องมีพฤติกรรมที่แตกต่างกัน ไม่ใช่เพียงข้อมูลที่แตกต่างกันเท่านั้น
Java อนุญาตให้คุณประกาศเมธอดนามธรรมในอีนัมและเขียนทับเมธอดนั้นสำหรับค่าคงที่แต่ละตัว รูปแบบนี้เรียกว่าการกำหนดบอดีเมธอดเฉพาะค่าคงที่
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));
}
}การทำงานของรูปแบบนี้
ค่าคงที่แต่ละตัวที่มีบอดีจะกลายเป็นคลาสย่อยนิรนามของอีนัม
เมธอดนามธรรมบังคับให้ค่าคงที่ทุกตัวต้องมีการใช้งานของตนเอง ดังนั้นคอมไพเลอร์จึงรับประกันความครบถ้วน
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));
}
}เครื่องคำนวณครบชุด
การดำเนินการทางคณิตศาสตร์ทั้งสี่แบบอยู่ในรูปค่าคงที่ แต่ละแบบมีบอดีของ apply เป็นของตนเอง
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));
}
}
}การผสานฟิลด์และพฤติกรรม
คุณสามารถผสานฟิลด์ (สัญลักษณ์) เข้ากับพฤติกรรมเฉพาะค่าคงที่ได้ ฟิลด์ใช้ระบุการดำเนินการ ส่วนเมธอดเป็นผู้ดำเนินการนั้น
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));
}
}เหตุใดจึงไม่ใช้คำสั่งสวิตช์
คุณสามารถใช้งาน apply ด้วยคำสั่งสวิตช์เดียวที่ตรวจสอบค่าคงที่ได้ แต่วิธีใช้เมธอดนามธรรมปลอดภัยกว่า
หากคุณเพิ่มค่าคงที่ในภายหลัง คอมไพเลอร์จะบังคับให้คุณกำหนดบอดีของค่าคงที่นั้น ส่วนคำสั่งสวิตช์อาจพลาดกรณีใหม่ไปโดยไม่แจ้งเตือน
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));
}
}เมธอดแบบรูปธรรมร่วมกับเมธอดนามธรรม
อีนัมสามารถมีทั้งเมธอดนามธรรมและเมธอดแบบรูปธรรมได้ ตรรกะที่ใช้ร่วมกันควรอยู่ในเมธอดแบบรูปธรรม ส่วนตรรกะที่แตกต่างกันควรคงไว้เป็นเมธอดนามธรรม
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));
}
}อีนัมกลยุทธ์
แนวทางต่อยอดคืออีนัมกลยุทธ์ ซึ่งค่าคงที่จะมอบหมายงานให้อีนัมกลยุทธ์แบบซ้อน แทนการเขียนทับโดยตรง
วิธีนี้มีประโยชน์เมื่อค่าคงที่หลายตัวมีพฤติกรรมเหมือนกัน ในตัวอย่างนี้ วันธรรมดาและวันหยุดสุดสัปดาห์มีการคำนวณ pay แตกต่างกัน
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));
}
}อีนัมที่มีอินเทอร์เฟซและบอดี
ผสานอินเทอร์เฟซเข้ากับบอดีเฉพาะค่าคงที่ เพื่อให้ได้พหุรูปแบบสูงสุด
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());
}
}การเข้าถึงฟิลด์จากบอดี
บอดีเฉพาะค่าคงที่สามารถอ่านฟิลด์ของค่าคงที่นั้นเองได้ เนื่องจากแต่ละบอดีทำงานในบริบทของอินสแตนซ์นั้น
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));
}
}กำหนดค่าเริ่มต้นแล้วเขียนทับ
คุณสามารถกำหนดค่าเริ่มต้นแบบรูปธรรมไว้ในบอดีของอีนัม แล้วเขียนทับเฉพาะค่าคงที่ที่มีพฤติกรรมแตกต่างกันได้
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"));
}
}เครื่องจักรสถานะขนาดย่อม
พฤติกรรมเฉพาะค่าคงที่มีประโยชน์อย่างมากในเครื่องจักรสถานะ เพราะแต่ละสถานะรู้จักการเปลี่ยนสถานะของตนเอง
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);
}
}ตรวจสอบความเข้าใจ
ทดสอบความเข้าใจของคุณเกี่ยวกับเมธอดนามธรรมของอีนัม
ทบทวน
คุณได้เรียนรู้พฤติกรรมเฉพาะค่าคงที่:
- ประกาศเมธอดนามธรรมและเขียนทับเมธอดนั้นในบอดีของค่าคงที่แต่ละตัว
- ค่าคงที่แต่ละตัวจะกลายเป็นคลาสย่อยนิรนาม
- คอมไพเลอร์บังคับให้กำหนดครบทุกกรณี จึงปลอดภัยกว่าการใช้คำสั่งสวิตช์
- ผสานฟิลด์ ค่าเริ่มต้นแบบรูปธรรม และอินเทอร์เฟซ เพื่อสร้างอีนัมที่มีความสามารถหลากหลาย
ถัดไป พบกับ 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());
}
}คำถามที่พบบ่อย
บทเรียน “เมธอดนามธรรมในอีนัม” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “เมธอดนามธรรมในอีนัม” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Java Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Java Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “เมธอดนามธรรมในอีนัม”
พฤติกรรมเฉพาะแต่ละค่าคงที่ คุณปฏิบัติ Java Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Java Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน Java Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน
บทเรียน “เมธอดนามธรรมในอีนัม” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน Java Academy นี้ได้ไหม
ได้ บทเรียน Java Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- อีนัมที่มีฟิลด์และเมธอด
- เมธอดนามธรรมในอีนัม
- EnumSet
- EnumMap