Java에서 열거형 확장
이 튜토리얼은 Java에서 enum
기능을 확장하는 방법을 보여줍니다.
Java에서 enum
확장
enum
은 byte
코드에서 enum
이 여러 정적
멤버가 있는 클래스로 표시되고 추상 java.lang.Enum
에서 상속되기 때문에 enum
을 일종의 컴파일러 마법으로 간주할 수 있습니다.
이것이 enum
이 다른 클래스 또는 enum
을 확장할 수 없는 이유입니다. Java에서 enum
을 확장할 수 없기 때문에 어떤 클래스에서도 enum
을 확장할 수 없습니다. 다음 예제 코드를 사용하여 배우고 무슨 일이 일어나는지 봅시다.
예제 코드:
package delftstack;
enum Cars { Audi, BMW, Marcedes }
public class Example extends Cars {
public static void main(String... args) {}
}
위의 코드에는 Cars
라는 enum
이 있고 Example
클래스는 이를 확장하려고 합니다. 출력 참조:
/Example.java:5: error: cannot inherit from final Cars
public class Example extends Cars {
^
/Example.java:5: error: enum types are not extensible
public class Example extends Cars {
^
2 errors
보시다시피 클래스는 enum
을 확장할 수 없습니다. 따라서 enum
을 확장하는 것이 불가능하더라도 그 기능을 계속 확장할 수 있습니까?
기능은 enum
에서 구현된 메소드로 정의할 수 있습니다. 예를 들어 위 코드의 enum
Cars
는 각 멤버에 대한 추상 메서드를 선언할 수 있습니다. 예를 참조하십시오.
enum Cars {
Audi {
@Override
public void drive() {}
},
BMW {
@Override
public void drive() {}
},
Mercedes {
@Override
public void drive() {}
},
;
public abstract void drive();
}
보시다시피 각 구성원은 drive()
메서드를 재정의할 수 있습니다. 그러나 불행히도 다음과 같은 이유로 enum
에서 메소드를 생성하는 것이 항상 가능한 것은 아닙니다.
enum
이 타사 라이브러리 또는 다른 팀에 속하는 경우 추상 메서드 구현을 허용하지 않습니다.drive()
메소드에 필요한 종속성이 없는 모듈에 속하는 경우.enum
이 다른 기능 및 데이터로 오버로드되면 읽을 수 없습니다.
이러한 문제를 해결하고 Java에서 enum
의 기능을 확장할 수 있는 몇 가지 솔루션이 제공됩니다.
해결 방법 1: Java에서 enum
미러링
이름에서 알 수 있듯이 동일한 데이터로 다른 enum
을 만들어야 합니다. 그 새로운 enum
은 drive()
메서드도 구현하므로 이제 두 개의 열거형이 있습니다.
enum Cars
에 대한 예제 코드:
enum Cars {
Audi {
@Override
public void drive() {}
},
BMW {
@Override
public void drive() {}
},
Mercedes {
@Override
public void drive() {}
},
;
public abstract void drive();
}
enum DriveCars
에 대한 예제 코드:
enum DriveCars {
Audi {
@Override
public void drive() {}
},
BMW {
@Override
public void drive() {}
},
Mercedes {
@Override
public void drive() {}
},
;
public abstract void drive();
}
두 번째 enum
은 첫 번째 항목의 미러입니다. 이제 기능을 확장하여 이 열거형을 모두 사용할 수 있습니다. name()
및 valueof()
인 내장 enum
메서드를 사용해야 합니다.
사용 방법에 대한 다음 예를 참조하십시오.
Cars cars = ... DriveCars.valueOf(cars.name()).drive();
위의 코드는 enum Cars
기능이 enum DriveCars
에서 어떻게 사용되는지 보여줍니다. 이는 기능이 확장되었음을 의미합니다.
위 코드에서 name()
메서드는 재정의할 수 없는 final
이며 valueOf
메서드는 컴파일러에서 생성됩니다. 이 두 가지 방법은 확장 작업에서 기능 오류가 없다는 점에서 서로 잘 맞습니다.
enum Cars
가 변경되면 위의 코드에 한 가지 문제가 있습니다. enum DriveCars
는 전혀 알지 못하고 name
및 valueof
트릭의 실패를 유발합니다. 이 문제를 해결하려면 상위 미러가 Cars
임을 DriveCars
에 알려야 합니다.
이를 위해 정적
초기화 프로그램을 사용하여 DriveCars
와 Cars
를 비교할 수 있습니다. 두 열거형이 일치하지 않으면 예외가 발생합니다. 다음은 enumus 라이브러리의 예입니다.
enum DriveCars {
....static { Mirror.of(Cars.class); }
}
유틸리티 클래스는 두 열거형이 일치하는지 여부를 확인합니다. 이 메소드는 name()
및 valueOf()
트릭을 검증합니다.
해결 방법 2: Java에서 enum
매핑
하나의 메소드만 보유하는 다른 enum
을 작성하지 않으려는 경우. 이 경우 enum
대신 interface
를 사용할 수 있습니다. 아래 예를 참조하십시오.
public interface Driver {
void drive();
}
이제 enum Cars
와 함께 이 인터페이스 드라이브
를 사용하기 위해 그들 사이에 매핑을 만들 수 있습니다. 지도의 예는 다음과 같습니다.
Map<Cars, Driver> drivers = new EnumMap<>(Cars.class) {
{
put(Audi, new Driver() {
@Override
public void driver() {}
}) put(BMW, new Driver() {
@Override
public void driver() {}
}) put(Mercedes, new Driver() {
@Override
public void driver() {}
})
}
}
이제 이를 사용하려면 다음과 같은 간단한 코드를 사용하십시오.
drivers.get(Cars).drive();
위의 코드에서 사용된 EnumMap
은 각 enum
멤버가 한 번만 표시되도록 보장하지만 각 멤버에 대한 항목을 보장하지는 않습니다.
지도의 크기가 enum의 멤버 수와 같은지 확인할 수 있습니다.
drivers.size() == Cars.values().length
enumus 라이브러리는 이 경우에 대한 유틸리티도 제공합니다. 지도가 Cars
에 맞지 않으면 IllegalStateException
이 발생합니다. 다음은 유틸리티입니다.
EnumMapValidator.validateValues(Cars.class, map, "Cars map");
위의 두 방법 모두 기능을 확장하여 enum을 강력하게 만드는 방법을 보여줍니다. enum
을 직접 확장하는 것은 불가능하지만 이러한 트릭을 사용하여 기능을 확장할 수 있습니다.
Sheeraz is a Doctorate fellow in Computer Science at Northwestern Polytechnical University, Xian, China. He has 7 years of Software Development experience in AI, Web, Database, and Desktop technologies. He writes tutorials in Java, PHP, Python, GoLang, R, etc., to help beginners learn the field of Computer Science.
LinkedIn Facebook