0Pricing
Java Academy · บทเรียน

เมธอดนามธรรมในอีนัม

พฤติกรรมเฉพาะแต่ละค่าคงที่

เมธอดนามธรรมในอีนัม เป็นบทเรียน 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 ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. อีนัมที่มีฟิลด์และเมธอด
  2. เมธอดนามธรรมในอีนัม
  3. EnumSet
  4. EnumMap
← กลับไปที่ Java Academy