자바/열거형(enums)

열겨형의 전반적인 개념(3)

백_곰 2022. 5. 17. 13:18

5. 열거형의 구조

- 아래와 같이 Direction이라는 열거형을 정의되었다고 가정해보자.

enum Direction{ EAST, SOUTH, WEST, NORTH };

 

( 이 열거형 Direction은 사실 상수 하나하나가 Direction 객체이다. )

 

 

( 그러므로, 위의 문장을 클래스로 정의하면 아래의 코드가 된다. )

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 상수들의 값은 객체의 주소이고, 이 값은 바뀌지 않는 값이므로 '=='으로 비교가 가능하다. )

 

 

( 또한 모든 열거형은 추상 클래스 Enum의 자손이므로, Enum을 흉내 내어 MyEnum을 작성하면 아래와 같다. )

abstract class MyEnum<T extends MyEnum<T>> implements Comparable<T> {
    static int id = 0;   // 객체에 붙일 일련번호 (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();
    }
}

 

( 만일 클래스를 MyEnum<T>와 같이 선언하였다면, compareTo()를 위와 같이 간단히 작성할 수 없었을 것이다. )

( 그 이유는 타입 T에 ordinal()이 정의되어 있는지 확인할 수 없기 때문이다. )

 

 

 

 

5-1. 열거형의 구조를 이해하기 위한 예제(1)

: 지금까지 배웠던 내용을 다룬 예제이다.

 

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", 150) {
		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", 300) {
		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; }
	public String toString() { return name; }
}

public class Exercise004 {
	public static void main(String[] args){
		MyTransportation t1 = MyTransportation.BUS;
		MyTransportation t2 = MyTransportation.BUS;
		MyTransportation t3 = MyTransportation.TRAIN;
		MyTransportation t4 = MyTransportation.SHIP;
		MyTransportation t5 = MyTransportation.AIRPLANE;
			
		System.out.printf("t1=%s, %d%n", t1.name(), t1.ordinal());
		System.out.printf("t2=%s, %d%n", t2.name(), t2.ordinal());
		System.out.printf("t3=%s, %d%n", t3.name(), t3.ordinal());
		System.out.printf("t4=%s, %d%n", t4.name(), t4.ordinal());
		System.out.printf("t5=%s, %d%n", t5.name(), t5.ordinal());
		System.out.println("t1==t2 ? "+(t1==t2));
		System.out.println("t1.compareTo(t3)="+ t1.compareTo(t3));
	}
}