Java에서 열거형 확장

Sheeraz Gul 2023년10월12일
Java에서 열거형 확장

이 튜토리얼은 Java에서 enum 기능을 확장하는 방법을 보여줍니다.

Java에서 enum 확장

enumbyte 코드에서 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을 만들어야 합니다. 그 새로운 enumdrive() 메서드도 구현하므로 이제 두 개의 열거형이 있습니다.

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는 전혀 알지 못하고 namevalueof 트릭의 실패를 유발합니다. 이 문제를 해결하려면 상위 미러가 Cars임을 DriveCars에 알려야 합니다.

이를 위해 정적 초기화 프로그램을 사용하여 DriveCarsCars를 비교할 수 있습니다. 두 열거형이 일치하지 않으면 예외가 발생합니다. 다음은 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 Gul
Sheeraz Gul avatar Sheeraz Gul avatar

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

관련 문장 - Java Enum