Java/Effective Java 3E
[이펙티브자바 3판] ITEM38. 확장할 수 있는 열거 타입이 필요하면 인터페이스를 사용하라
잭피
2020. 11. 18. 22:13
이번장의 핵심은...
열거 타입 자체는 확장할 수 없지만, 인터페이스와 그 인터페이스를 구현하는 기본 열거 타입을 함께 사용해 같은 효과를 낼 수 있다
열거 타입은 확장할 수 없다
타입 안전 열거 패턴은 열거한 값들에 값을 더 추가하여 다른 목적으로 사용할 수 있지만, 열거 타입은 불가능
확장할 수 있는 방법?
열거 타입이 인터페이스를 구현할 수 있다는 아이디어를 이용
연산 코드용 인터페이스를 정의하고 열거 타입이 이를 구현하도록 함
public interface Operation {
double apply(double x, double y);
}
// 인터페이스를 이용해 확장 가능 열거 타입을 흉내
public enum BasicOperation implements Operation {
PLUS("+") {
public double apply(double x, double y) { return x + y; }
},
MINUS("-") {
public double apply(double x, double y) { return x - y; }
},
TIMES("*") {
public double apply(double x, double y) { return x * y; }
},
DIVIDE("/") {
public double apply(double x, double y) { return x / y; }
};
private final String symbol;
BasicOperation(String symbol) {
this.symbol = symbol;
}
@Override public String toString() {
return symbol;
}
}
열거타입인 BasicOperation은 확장할 수 없지만, 인터페이스 Operation은 확장이 가능
아래처럼 Operation을 구현해 또 다른 열거 타입을 정의할 수 있음
public enum ExtendedOperation implements Operation {
EXP("^") {
public double apply(double x, double y) {
return Math.pow(x, y);
}
},
REMAINDER("%") {
public double apply(double x, double y) {
return x % y;
}
};
private final String symbol;
ExtendedOperation(String symbol) {
this.symbol = symbol;
}
@Override public String toString() {
return symbol;
}
}
apply 메소드는 인터페이스에 선언되어 있으니 열거 타입에 따로 추상 메서드로 선언하지 않아도 됨
개별 인스턴스 수준에서뿐 아닌 타입 수준으로도 사용가능 2가지 방식
public static void main(String[] args) {
1. test(ExtendedOperation.class, x. y)
2. test(Arrays.asList(ExtendedOperation.values()), 2.0, 4.0);
}
// 1. class 리터럴은 열거타입이면서 Operation 하위 타입 (opEnumType)
private static <T extends Enum<T> & Operation> void test(
Class<T> opEnumType, double x, double y) {
for (Operation op : opEnumType.getEnumConstants())
System.out.printf("%f %s %f = %f%n",
x, op, y, op.apply(x, y));
}
// 2. Class 대신 한정적 와일드카드 타입을 넘김
private static void test(Collection<? extends Operation> opSet,
double x, double y) {
for (Operation op : opSet)
System.out.printf("%f %s %f = %f%n",
x, op, y, op.apply(x, y));
}
인터페이스를 이용해 확장 가능한 열거 타입을 만드는 방식에도 한 가지 문제가 있음
열거 타입끼리 구현을 상속할 수 없다
따라서 같은 인터페이스를 구현한 열거 타입에 각각에 필요한 메서드를 구현해야함
공유하는 기능이 많다면 별도의 도우미 클래스나 정적 도우미 메소드로 분리하는 방식으로 코드 중복을 피하자
이 글은 “이펙티브 자바 3판” 책 내용을 정리한 글입니다.
만약 저작권 관련 문제가 있다면 “shk3029@kakao.com”로 메일을 보내주시면, 바로 삭제하도록 하겠습니다.