-
자바 - 열거형(enums)언어/JAVA 2023. 3. 26. 16:51
1. 열거형이란?
- 열거형은 서로 관련된 상수를 묶어놓은 것이다. java의 열거형은 타입도 관리하여 타입에 안전한 열거형이다.
- 마치 인스턴스가 미리 정의된 클래스로 생각해 볼 수 있다.
1.2 열거형의 정의와 사용
- enum 열거체명 {상수명1,상수명2..} 등으로 정의할 수 있다.
- 선언 위치는 클래스와 동일하다. 클래스 내부, 외부, 혹은 하나의 클래스파일에 정의할 수 있다.
- 사용법은 열거체 참조변수에 열거체.상수명 혹은 열거형체.valueOf(상수명)
- 모든 열거형의 조상 Enum에 Enum에 기본적으로 사용가능한 메서드들이 정의되어 있다.
enum Direction {EAST,SOUTH,WEST,NORTH} Direction dir = Direction.EAST; Direction dir2 = Direction.valueOf("SOUTH");
1.3 열거형에 멤버 추가하기
- 열거형 멤버에 여러 값을 할당 할 수 있다.
- 이때 열거형 멤버들은 미리 선언된 인스턴스와 같고, 열거형 내부에서 인스턴스를 생성하기 위한 생성자 및 메서드를 정의 해야한다. (내부적으로 사용되는 생성자와 변수는 private)
enum Direction { EAST(1,">"),SOUTH(2,"v"),WEST(3,"<"),NORTH(4,"^"); private final int value; private final String symbol; private Direction(int value,String symbol){ this.value= value; this.symbol = symbol; } public int getValue() {return this.value;} }
1.4 추상 메서드 추가하기
- 열거형에 추상메서드를 추가해서 열거형 멤버들이 이를 오버라이딩하게 할 수 있다.
- 이는 마치 추상클래스를 상속받은 클래스가 오버라이딩하는 것과 같다.
- 각 열거체의 상수별로 오버라이딩을 통해 메서드 내용을 다르게 설정할 수 있다.
enum Direction { EAST(1,">"){ @Override int fare() { return EAST.getValue()*2; } },SOUTH(2,"v") { @Override int fare() { return SOUTH.getValue()+Basic_fare; } },WEST(3,"<") { @Override int fare() { return WEST.getValue()+Basic_fare; } },NORTH(4,"^") { @Override int fare() { return NORTH.getValue()+Basic_fare; } }; private final int value; private final String symbol; protected final int Basic_fare=2; //protected로 해야 각 열거형 멤버들이 모두 접근 가능 private Direction(int value,String symbol){ this.value= value; this.symbol = symbol; } abstract int fare(); public int getValue() {return this.value;} }
2. 열거형의 이해
열거형에 대한 더 싶은 이해를 위해 내부 구현에 대해 간단하게 살펴보자
enum Direction {EAST,SOUTH,WEST,NORTH}는 아래 코드와 같다.
class Direction{ static final Direction EAST = new Direction("EAST"); static final Direction SOUTH = new Direction("SOUTH"); static final Direction WEST = new Direction("WEST"); static final Direction NORTH = new Direction("NORTH"); private String name; private Direction(String name) { this.name=name; } }
- static 상수 열거형 객체 EAST,SOUTH,WEST,NORTH는 객체의 주소를 담고 있고, 이 값은 바뀌지 않으므로 ==로 비교 가능
- 또한 static 상수이므로 열거형이름.EAST등으로 사용가능한 것이다.
abstract class MyEnum<T extends MyEnum<T>> implements Comparable<T>{ static int id=0; int ordinal; String name =""; public int ordinal(){return ordinal;} MyEnum(String name){ this.name = name; ordinal = id++; } public int compareTo(T t){ return ordinal - t.ordinal(); } } abstract class MyTransportation extends MyEnum{ static final MyTransportation BUS = new MyTransportation("BUS",100) { int fare(int distance) {return distance * BASIC_FARE; } }; static final MyTransportation TRAIN = new MyTransportation("TRAIN",100) { int fare(int distance) {return distance * BASIC_FARE; } }; static final MyTransportation SHIP = new MyTransportation("SHIP",100) { int fare(int distance) {return distance * BASIC_FARE; } }; static final MyTransportation AIRPLANE = new MyTransportation("AIRPLANE",100) { int fare(int distance) {return distance * BASIC_FARE; } }; abstract int fare(int distance); protected final int BASIC_FARE; private MyTransportation(String name, int basicfare) { super(name); BASIC_FARE = basicfare; } public String name(){return name;} }
- 객체가 생성될 때마다 ordinal에 저장
- <T enxtends MyEnum<T>> 타입 T가 MyEnum<T>의 자손이어야 한다는 의미 (compareTo에서 t.ordinal()때문에 이렇게함)
- 추상메서드를 추가하면, 클래스 앞에 abstract 각 static 멤버들 익명클래스 형태로 추상메서드 구현
**여기서 MyEnum<T> <- 이 <T>는 큰 의미는 없다.
T extedns MyEnum인 것과 마찬가지 -> 제네릭 클래스에서 타입변수의 다형성 x (원시타입은 다형성 인정, 타입변수는 안됨)
따라서 MyEnum<String,Integer...등등 뭐던 간에> T는 MyEnum<> 혹은 그 자손만 담을 수 있다.
참고자료- 자바의 정석 남궁성 저
'언어 > JAVA' 카테고리의 다른 글
객체지향 - 캡슐화 (0) 2023.06.12 자바 - 입출력(I/O) (1) 바이트기반 스트림/ 문자기반 스트림 (0) 2023.05.14 자바 - Arrays 클래스와 Comparator (0) 2023.03.23 자바 - Thread(4) 동기화 (0) 2023.03.21 자바 - thread(3) 실행제어 메서드 예제 (0) 2023.03.21