이펙티브 자바, 쉽게 정리하기 - item 38. 확장할 수 있는 열거 타입이 필요하면 인터페이스를 사용하라
열거 타입의 확장
- 기본적으로 열거 타입의 확장이 지원되지는 않는다.
- 그러나 가끔 필요할 때, 인터페이스를 통해 확장하면 된다.
public interface Operation {
double apply(double x, double y);
}
public enum BasicOperation implements Operation {
PLUS("+") {
@Override
public double apply(double x, double y) {
return x+y;
}
},
MINUS("-") {
@Override
public double apply(double x, double y) {
return x-y;
}
},
TIMES("*") {
@Override
public double apply(double x, double y) {
return x*y;
}
},
DIVIDE("/") {
@Override
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;
}
}
public enum ExtendedOperation implements Operation {
EXP("^") {
@Override
public double apply(double x, double y) {
return Math.pow(x, y);
}
},
REMAINDER("%") {
@Override
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;
}
}
- 확장한 코드의 예이다.
Operation
인터페이스를 구현하여,BasicOperation
과ExtendedOperation
을 만들었다.- 지원하는 메서드의 형태가 같아 어디서든 대체하여 쓸 수 있다.
클라이언트 코드로 실행시켜보기: 1 클래스로 받아보기
@Test
public void operationTest() {
double x = 4.0;
double y = 2.0;
getEnumClass(BasicOperation.class, x, y);
getEnumClass(ExtendedOperation.class, x, y);
}
private <T extends Enum<T> & Operation> void getEnumClass(Class<T> enumClass, double x, double y) {
for (Operation operation : enumClass.getEnumConstants()) {
System.out.printf("%f %s %f = %f%n", x, operation, y, operation.apply(x, y));
}
}
enum
타입의 클래스를 받아getEnumConstants()
를 통해 클래스가 가진apply
메서드들을 실행해보았다.<T extends Enum<T> & Operation>
의 의미는enum
이며Operation
을 상속받았음을 이야기한다.
클라이언트 코드로 실행시켜보기: 2 컬렉션으로 받아보기
@Test
public void operationTest() {
double x = 4.0;
double y = 2.0;
getEnumCollection(Arrays.asList(BasicOperation.values()), x, y);
getEnumCollection(Arrays.asList(ExtendedOperation.values()), x, y);
}
private void getEnumCollection(Collection<? extends Operation> opSet, double x, double y) {
for (Operation operation : opSet) {
System.out.printf("%f %s %f = %f%n", x, operation, y, operation.apply(x, y));
}
}
enum
타입의 값이 들어있는List
를 넘겨본 형태이다.- 둘 다 잘 동작한다만, 특정 연산에서는
EnumSet
과EnumMap
을 사용하지 못하는 단점이 있다.
정리
- 열거 타입(
enum
)은 확장할 수 없다. - 단, 인터페이스를 통해 여러 열거 타입에 동일한 인터페이스를 구현하게 하면 마치 확장하는 것과 비슷한 효과를 낸다.
- 인터페이스로 작성되었다는 가정하에 서로 얼마든지 대체도 가능하다.
반응형
'Java > 이펙티브 자바' 카테고리의 다른 글
이펙티브 자바, 쉽게 정리하기 - item 40. @Override 애너테이션을 일관되게 사용하라 (0) | 2022.05.24 |
---|---|
이펙티브 자바, 쉽게 정리하기 - item 39. 명명 패턴보다 애너테이션을 사용하라 (0) | 2022.05.24 |
이펙티브 자바, 쉽게 정리하기 - item 37. ordinal 인덱싱 대신 EnumMap을 사용하라 (0) | 2022.02.24 |
이펙티브 자바, 쉽게 정리하기 - item 36. 비트 필드 대신 EnumSet을 사용하라 (0) | 2022.02.24 |
이펙티브 자바, 쉽게 정리하기 - item 35. ordinal 메서드 대신 인스턴스 필드를 사용하라 (0) | 2022.02.24 |