Item 34. 확장 가능한 enum을 만들어야 한다면 인터페이스를 이용하라.
public interface Operation{
double apply(doube x, double y);
}
public enum BasicOperation implements Operation{
PLUS("+") {double apply(double x, double y) {return x + y;}},
MINUS("-") {double apply(double x, double y) {return x - y;}},
TIMES("*") {double apply(double x, double y) {return x * y;}},
DIVIDE("/") {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은 enum자료형이라 계승할 수 없지만 Operation은 인터페이스라 확장이 가능하다.
public enum ExtendedOperation implements Operation {
EXP("^") {double apply(double x, double y) {return Math.pow(x,y);}}
REMAINDER("%") {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;
}
}
1. 한정적 자료형 토근(bounded type token)
public static void main(String[] args) {
double x = Double.parseDouble(args[0]);
double y = Double.parseDouble(args[1]);
test(ExtendedOperation.class, x, y);
}
private static <T extends Enum<T> & Operation> void test(Class <T> ops, double x, double y) {
for (Operation op : ops.getElementConstants()) {
System.out.printf("%f %s %f = %f%n", x, op, op.apply(x, y));
}
}
<T extends Enum<T> & Operation>
타입 파라미터는 Class<T>
객체가 나타내는 자료형이 enum자료힝인 동시에 Operation의 하위 자료형이 되도록 한다.
2. 한정적 와일드 카드 자료형 사용
public static void main(String[] args) {
double x = Double.parseDouble(args[0]);
double y = Double.parseDouble(args[1]);
test(Arrays.asList(ExtendedOperation.values()), x, y);
}
private static void test(Collection< ? extends Operation> ops, double x, double y) {
for (Operation op : ops) {
System.out.printf("%f %s %f = %f%n", x, op, op.apply(x, y));
}
}
결론
계승 가능 enum자료형은 만슬수 없지만, 인터페이스를 만들고 그 인터페이스를 구현하는 기본 enum자료형을 만들면 계승 가능 enum자료형을 흉내 낼수 있다.