*알림 : *
Effective Java 3판은 Java 9까지 도입된 언어적 기능을 중심으로 서술되어 있습니다. 10버젼 이후의 Java 개발을 하시는 분들은 우회적인 접근법 대신 Java 언어 내 새로 도입된 기능이 더 간결하고 좋을 수 있습니다.해당 포스팅은 SSAFY 내 책읽기 스터디의 활동을 통해 작성된 포스팅입니다.
https://github.com/kjsu0209/JavaBook
https://medium.com/javabook
Enum type은 확장을 할 수 없다. OOP의 상속의 시점으로 본다면, 확장한 타입들의 원소는 상위 타입의 원소가 되지만, 그 반대는 성립하지 않는다. 순회할 방법도 마땅치 않다. 설계와 구현의 난이도도 올라갈 것이다.
그러나 Enum 타입은 인터페이스를 구현할 수 있다.
예제 1 : 연산 코드(Operation Code)
// 인터페이스 정의
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;
}
}
Enum 타입인 BasicOperation*은 확장할 수 없지만, *Operation 인터페이스는 확장이 가능하다. 사칙연산 뿐 아니라 mod 연산과 exp 지수연산을 추가하고 싶다고 가정하자. Operation 인터페이스를 확장해 구현하기만 하면 된다.
예제 1-1 : 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;
}
}
인터페이스를 확장한 덕에, 처음 고안했던 BasicOperation 뿐 아니라 ExtendedOperation도 인터페이스를 통해 접근할 수 있다.
예제 2 : 확장된 Enum 타입을 인터페이스로 접근하기
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> opSet,
double x, double y) {
for (Operation op : opSet)
System.out.printf("%f %s %f = %f%n",
x, op, y, op.apply(x, y));
}
}
ExtendedOperation.values()*는 상수의 배열을 반환한다. 앞서 다뤘던 아이템에서 보았듯이 가능하면 배열보다는 List를 사용하길 권장하므로, *Arrays.asList() 메서드로 배열을 리스트로 변환한다.
한정적 타입을 통해 Operation을 확장한 무언가를 담고있는 Collection을 test 메서드에서 인자로 받는다.
확장한 타입의 코드 중복작성을 줄이는 테크닉
그러나 열거타입끼리 상속을 구현할 수 없는 문제는 여전하다. 그러나 확장한 Enum 타입끼리 많은 로직을 공유해야 한다면?
- 별도의 Helper class 작성
- Static helper method로 분리
- 인터페이스의 default 메서드
'IT > Effective Java' 카테고리의 다른 글
[Effective Java 3/E] ITEM 40. @Override Annotation을 일관적으로 사용하기 (0) | 2021.03.28 |
---|---|
[Effective Java 3/E] ITEM 39. 명명 패턴보다 애너테이션을 사용하라 (0) | 2021.03.28 |
[Effective Java 3/E] ITEM 37. ordinal 인덱싱 대신 EnumMap을 사용하라 (0) | 2021.03.28 |
[Effective Java 3/E] ITEM 36. 비트 필드 대신 EnumSet을 사용하라 (0) | 2021.03.28 |
[Effective Java 3/E] ITEM 35. ordinal 메서드 대신 인스턴스 필드를 사용하라 (0) | 2021.03.28 |
댓글