0Pricing
Java Academy · 강의

열거형의 추상 메서드

상수별 동작을 구현합니다

열거형의 추상 메서드은(는) CoddyKit의 무료 Java Academy 강의입니다. 이것은 4개 중 2번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 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));
    }
}

전략 열거형

한 단계 더 발전시킨 방식은 전략 열거형입니다. 상수가 직접 메서드를 재정의하는 대신 중첩된 전략 열거형에 작업을 위임합니다.

여러 상수가 같은 동작을 공유할 때 유용합니다. 여기서는 평일과 주말의 급여 계산 방식이 다릅니다.

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());
    }
}

자주 묻는 질문

“열거형의 추상 메서드” 강의는 무료인가요?

네 — “열거형의 추상 메서드” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 Java Academy 강의 전체를 잠금 해제할 수 있습니다. Java Academy 강의에는 총 4개의 강의가 포함되어 있습니다.

“열거형의 추상 메서드”에서 뭘 배우나요?

상수별 동작을 구현합니다 브라우저에서 직접 실행하는 실습 코드로 Java Academy을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.

Java Academy을(를) 시작하는 데 경험이 필요한가요?

사전 경험은 필요하지 않습니다. CoddyKit의 Java Academy은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 2번째 강의입니다.

“열거형의 추상 메서드” 강의는 얼마나 걸리나요?

대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.

이 Java Academy 강의에서 코드를 작성하고 실행할 수 있나요?

네. 모든 Java Academy 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.

이 강의의 모든 강의

  1. 필드와 메서드가 있는 열거형
  2. 열거형의 추상 메서드
  3. EnumSet
  4. EnumMap
← Java Academy(으)로 돌아가기