[java] Enum 추상 메서드 활용과 이해

2025. 10. 3. 22:35·공부일기../Java

1. Enum도 사실은 클래스다

우리가 흔히 쓰는 Enum은 사실 특별한 클래스다.

public enum PaymentType {
    CARD, BANK, KAKAO
}

 

이 코드는 내부적으로 이렇게 동작한다

public class PaymentType {
    public static final PaymentType CARD = new PaymentType();
    public static final PaymentType BANK = new PaymentType();
    public static final PaymentType KAKAO = new PaymentType();
    
    private PaymentType() {}  // private 생성자
}

그래서 Enum도 클래스처럼 필드와 메서드를 가질 수 있다.

 


2. Enum 본체란 ?

Enum은 두 부분으로 나뉜다

  1. 상수 선언부 (위쪽)
  2. 본체 (아래쪽)
public enum PaymentType {
    // ========== 1. 상수 선언부 ==========
    CARD, BANK, KAKAO;  // 세미콜론(;)으로 끝
    
    // ========== 2. Enum 본체 ==========
    // 여기서부터는 일반 클래스처럼 메서드를 정의할 수 있다
    public void printType() {
        System.out.println("결제 타입: " + this.name());
    }
    
    public String getDescription() {
        return "결제 수단";
    }
}

상수 선언이 끝나면 세미콜론(;)을 찍고 그 다음부터가 "본체"다.

 


 

3. 각 상수마다 다른 동작이 필요하다면?

만약 CARD, BANK, KAKAO가 각각 다른 결제 프로세서를 생성해야 한다면?

 

방법 1: switch문 사용 (별로 안 좋음)

public enum PaymentType {
    CARD, BANK, KAKAO;
    
    public PaymentProcessor createProcessor() {
        switch(this) {
            case CARD:
                return new CardPaymentProcessor();
            case BANK:
                return new BankPaymentProcessor();
            case KAKAO:
                return new KakaoPaymentProcessor();
            default:
                throw new IllegalArgumentException();
        }
    }
}

문제점 새 결제 수단 추가 시 switch문을 수정해야 한다. (OCP 위반)

 

 

방법 2: 추상 메서드 사용 (추천!)

public enum PaymentType {
    // ========== 상수 선언부 ==========
    CARD {
        @Override
        public PaymentProcessor createProcessor() {
            return new CardPaymentProcessor();
        }
    },
    BANK {
        @Override
        public PaymentProcessor createProcessor() {
            return new BankPaymentProcessor();
        }
    },
    KAKAO {
        @Override
        public PaymentProcessor createProcessor() {
            return new KakaoPaymentProcessor();
        }
    };  // 마지막 세미콜론!
    
    // ========== Enum 본체 ==========
    public abstract PaymentProcessor createProcessor();
}

 

 


 

 

4. 각 상수의 중괄호의 의미

CARD {
    @Override
    public PaymentProcessor createProcessor() {
        return new CardPaymentProcessor();
    }
}

이 중괄호 {}는 익명 클래스(Anonymous Class) 문법이다.

 

실제로는 이렇게 동작한다.

public static final PaymentType CARD = new PaymentType() {
    @Override
    public PaymentProcessor createProcessor() {
        return new CardPaymentProcessor();
    }
};

CARD는 PaymentType을 상속받은 익명 클래스의 인스턴스다.

 

 


 

5. 추상 메서드 사용

에러상황

public enum PaymentType {
    CARD, BANK, KAKAO;  // 메서드 구현 안 함
    
    public abstract PaymentProcessor createProcessor();  // 추상 메서드
}

 

컴파일 에러 발생!

Error: PaymentType.CARD is not abstract and does not override abstract method createProcessor()

컴파일러가 "CARD가 createProcessor() 구현 안 했어!"라고 알려준다.

 

컴파일 실수 방지

public enum PaymentType {
    CARD {
        @Override
        public PaymentProcessor createProcessor() {
            return new CardPaymentProcessor();
        }
    },
    BANK {
        @Override
        public PaymentProcessor createProcessor() {
            return new BankPaymentProcessor();
        }
    },
    NAVER {
        // 메서드 구현 깜빡함!
    };  // ← 컴파일 에러!
    
    public abstract PaymentProcessor createProcessor();
}

새 상수를 추가하고 메서드 구현을 깜빡하면 컴파일 에러가 난다.

런타임 에러가 아니라 컴파일 타임에 잡아준다!

 

 


 

6. 전체 구조 정리

public enum PaymentType {
    // ===== 1단계: 각 상수가 메서드를 구현 =====
    CARD {
        @Override
        public PaymentProcessor createProcessor() {
            return new CardPaymentProcessor();
        }
    },  // 쉼표
    
    BANK {
        @Override
        public PaymentProcessor createProcessor() {
            return new BankPaymentProcessor();
        }
    },  // 쉼표
    
    KAKAO {
        @Override
        public PaymentProcessor createProcessor() {
            return new KakaoPaymentProcessor();
        }
    };  // 세미콜론! (마지막 상수 뒤)
    
    // ===== 2단계: Enum 본체에 추상 메서드 선언 =====
    public abstract PaymentProcessor createProcessor();
}

// ===== 3단계: 공통 인터페이스 정의 =====
interface PaymentProcessor {
    void process(int amount);
}

// ===== 4단계: 각 프로세서 구현 =====
class CardPaymentProcessor implements PaymentProcessor {
    public void process(int amount) {
        System.out.println("카드 결제: " + amount);
    }
}

class BankPaymentProcessor implements PaymentProcessor {
    public void process(int amount) {
        System.out.println("계좌이체: " + amount);
    }
}

class KakaoPaymentProcessor implements PaymentProcessor {
    public void process(int amount) {
        System.out.println("카카오페이: " + amount);
    }
}

 

 


 

7. 사용 예시

public class PaymentService {
    public void pay(PaymentType type, int amount) {
        // 각 타입이 자신만의 프로세서를 생성한다
        PaymentProcessor processor = type.createProcessor();
        processor.process(amount);
    }
}

// 호출
PaymentService service = new PaymentService();
service.pay(PaymentType.CARD, 10000);   // 출력: 카드 결제: 10000
service.pay(PaymentType.KAKAO, 5000);   // 출력: 카카오페이: 5000

 

 


 

8. 핵심 정리

  1. Enum도 클래스다 - 메서드를 가질 수 있다
  2. 상수 선언부와 본체를 세미콜론(;)으로 구분한다
  3. 추상 메서드를 본체에 선언하면 각 상수가 반드시 구현해야 한다
  4. 각 상수의 중괄호는 익명 클래스 문법이다
  5. 컴파일 타임에 실수를 잡아준다 - 런타임 에러 방지

 


 

 

9. 사용하면 좋은 상황

  • 각 상수마다 다른 동작이 필요할 때
  • switch문을 없애고 싶을 때
  • 새 타입 추가 시 컴파일러의 도움을 받고 싶을 때
  • 타입 안정성을 확보하고 싶을 때

'공부일기.. > Java' 카테고리의 다른 글

[디자인패턴] 자바 전략 패턴(Strategy Pattern)  (0) 2025.11.25
[java] 예외 처리와 트랜잭션 롤백 (PSA (Portable Service Abstraction))  (0) 2025.10.29
[코테] JAVA 백준 알고리즘 시작하기 - 입출력 가이드 !!성능최적화!!  (0) 2025.09.29
[java] 자바 파일 처리 기본기 가이드 - 주니어 개발자 필수 FILE/FILES  (0) 2025.09.22
[java] static 제대로 활용하기 - 패턴과 함정  (0) 2025.09.21
'공부일기../Java' 카테고리의 다른 글
  • [디자인패턴] 자바 전략 패턴(Strategy Pattern)
  • [java] 예외 처리와 트랜잭션 롤백 (PSA (Portable Service Abstraction))
  • [코테] JAVA 백준 알고리즘 시작하기 - 입출력 가이드 !!성능최적화!!
  • [java] 자바 파일 처리 기본기 가이드 - 주니어 개발자 필수 FILE/FILES
s0-0mzzang
s0-0mzzang
공부한것을 기록합니다...
  • s0-0mzzang
    승민이의..개발일기..🐰
    s0-0mzzang
  • 전체
    오늘
    어제
    • 전체~ (108)
      • 마음가짐..! (10)
      • 공부일기.. (76)
        • weekly-log (6)
        • Spring (19)
        • Java (18)
        • DataBase (10)
        • git (2)
        • JPA (6)
        • kafka (1)
        • Backend Architecture (3)
        • Troubleshooting (삽질..ㅋ) (2)
        • Cloud (1)
        • Docker (2)
        • 알고리즘 (1)
        • 리액트 (2)
        • Infra (3)
      • 하루일기.. (22)
        • 그림일기 (8)
        • 생각일기 (14)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

    • 깃허브
  • 공지사항

  • 인기 글

  • 태그

    JPA
    StringTokenizer
    spring
    스프링부트
    다짐
    swagger
    BufferedReader
    React
    항해99
    SpringBoot
    spring boot
    Paging
    MySQL
    자바
    TDD
    ADC 환경
    리팩토링
    항해플러스
    인프라 기초
    ERD
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
s0-0mzzang
[java] Enum 추상 메서드 활용과 이해
상단으로

티스토리툴바