티스토리 뷰

자바의 enum은 타입 안전한 상수를 선언하기 위한 야무진 도구다

Java1.5부터 등장했고 상수 집합을 나타내는 특별한 데이터 타입이다 

다만 모든 것이 일장일단이 있듯 enum도 상속할 수 없다는 단점이 존재한다

우선 왜 enum은 상속할 수 없는지 그 이유부터 알아보자

 

https://stackoverflow.com/questions/19433364/why-cant-a-class-extend-an-enum

 

가능한 값들의 닫힌 집합을 만들기 위해서다

닫힌 집합이란 컴파일 시점에 가능한 값들을 모두 알기 위해서고 이 방식이 개발자나 컴파일러 모두에게 이롭다고 한다

확장이 가능하다면 메서드의 인자로 A라는 enum을 받는 경우

리스코프 치환 원칙에 따라 A를 상속한 B라는 enum도 받을 수 있어야 한다

이런 경우 switch-case에서 사용할 수 없다

- switch(A) 라고 선언했는데 런타임에 B가 들어올 수 있다면 모든 case에 대응할 수 없기 때문

 

설계 목적 상 값들의 집합을 나타내기 위해 만들었는데

이를 확장해서 새로운 값을 추가할 수 있다면 뭐하러 enum을 만들었겠는가?

따라서 변하지 않으며 타입 안전한 데이터 타입을 만들기 위해 enum을 설계한 결과로 상속을 허용하지 않는다

 

https://www.baeldung.com/java-extending-enums

 

밸덩을 참고해 기술적인 측면으로 enum을 상속할 수 없는 이유를 보자

컴파일러가 마법을 부려 추상 클래스인 Enum을 상속받게 하고 나아가 상속받을 수 없도록 final 클래스로 막아둔다

따라서 이미 한번 상속을 받은 클래스가 되고 확인 사살로 final 클래스로 만들어져 있기 때문에 extends 금지다

추상 클래스를 상속받은 덕에 valueOf(), name()을 사용할 수 있고 역직렬화 방어도 야무지게 되어있어서

싱글턴을 구현할 때 가장 간편한 방법으로 enum을 사용할 수도 있다

 

java.lang.Enum

 

타입 안전한 것도 좋고 싱글턴을 구현할 수 있는 것도 좋지만 상속받을 수 없다는 건 역시 아쉽다

그렇기 때문에 enum이라도 인터페이스를 구현할 수 있다는 점에서 시작해 꼼수를 부려볼 수 있다

책의 예제를 그대로 가져왔다

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", x, op, y, op.apply(x, y));
}

 

매개변수 타입을 설정하는 부분이 중요한데 T는 java.lang.Enum을 상속받기 때문에

Enum<T>의 하위 클래스라 할 수 있고 Operation은 확장을 위한 꼼수 인터페이스다

enum 타입 클래스라면 opEnumType의 자리에 A.class 형태로 들어갈 수 있다

Enum으로 한정 지어 놨기 때문에 getEnumConstants()를 사용하여 값들을 가져올 수 있고

Operation이라는 인터페이스를 구현했기 때문에 미리 정의해둔 메서드를 구현해 다형성을 이용할 수도 있다

 

 

이 방식을 쓰는 상황이 얼마나 되겠느냐만 가능한 방식임을 알아두고 더 중요한 핵심을 꿰뚫어 보자

인터페이스는 확장의 중심이고 심지어 상속할 수 없는 enum 마저 다형성을 이용해 활용할 수 있게 된다

'Java > Effective Java' 카테고리의 다른 글

[Item40] 긴가 민가 할 땐 붙여라  (0) 2022.03.24
[Item39] Lombok 알아보기  (0) 2022.03.22
[Item37] Collectors.groupingBy로 EnumMap 만들기  (0) 2022.03.20
[Item36] 비트 필드와 EnumSet  (0) 2022.03.19
[Item35] ordinal 금지  (0) 2022.03.15
댓글
링크
글 보관함
«   2024/04   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
Total
Today
Yesterday