[이펙티브 자바] 아이템 38. 확장할 수 있는 열거 타입이 필요하면 인터페이스를 사용하라

June·2022년 3월 9일
0

[이펙티브자바]

목록 보기
35/72

열거 타입은 보통은 확장에 적합하지 않다.

확장할 수 있는 열거타입이 필요할 때도 있는데 연산 코드가 그 예시다. 사용자 확장 연산을 추가할 수 있도록 열어주는 것이다.

열거 타입이 임의의 인터페이스를 구현하면 된다.

인터페이스를 이용해 확장 가능 열거 타입을 흉내냈다.

public interface Operation {
    double apply(double x, double y);
}
public enum BasicOperation implements Operationn {
    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;
    }
}

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;
    ...
}

inteface를 구현하는 여러 enum들에 접근할 수 있다.

public static void main(String[] args) {
    double x = 10;
    double y = 2;
    test(Arrays.asList(ExtendedOperation.values()), x, y);
}

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

단점은 같은 interface를 implements하는 구현체 enum끼리는 상속이 불가능하다.
공통 부분이 많지 않다면 같은 interface내에서 디폴트 메서드로 구현하고, 공통 부분이 많다면 별도의 도우미 클래스나 정적 도우미 메서드로 분리하자.

0개의 댓글

관련 채용 정보