JAVA - 열거형(enums)

DevSeoRex·2022년 12월 6일
0
post-thumbnail

열거형(enums)이란?

  • 열거형은 서로 관련된 여러 상수를 편리하게 선언하기 위해 만들어졌다.
  • 자바에는 열거형이 존재하지 않았으나, JDK 1.5부터 추가되었다.
  • 자바의 열거형은 갖는 값뿐만 아니라 타입도 관리하기 때문에 논리적인 오류를 줄일 수 있다.
  • 상수의 값이 바뀌면 해당 상수를 참조하는 모든 소스를 다시 컴파일해야 했지만, 열거형 상수를 사용하면 기존의 소스를 다시 컴파일하지 않아도 되는 이점이 있다.
// 열거형을 사용하기 전 - 클래스 내에 상수를 선언
class Card {
	static final int CLOVER = 0;
    static final int HEART = 1;
    static final int DIAMOND = 2;
    static final int SPADE = 3;
    
    static final int TWO = 0;
    static final int THREE = 1;
    static final int FOUR = 2;
    
    final int kind;
    final int num;
}

// 열거형을 사용 - enum 으로 상수를 정의
class Card {
	enum Kind 	{ CLOVER, HEART, DIAMOND, SPADE }		// 열거형 Kind를 정의
    enum Value	{ TWO, THREE, FOUR }					// 열거형 Value를 정의
    
    final Kind kind;		// 타입이 int가 아닌 Kind임에 주의해야 한다.
    final Value value;
} 

💡 자바의 열거형은 '타입에 안전한 열거형'이므로, 실제 값이 같아도 타입이 다르면 컴파일 에러가 발생한다.

열거형의 정의와 사용방법

  • 열거형을 정의하려면 괄호 { }안에 상수의 이름을 나열하기만 하면 된다.

  • 열거형에 정의된 상수를 사용하는 방법은 '열거형이름.상수명'이다. 클래스의 static 변수를 참조하는 것과 유사하다.

  • 열거형 상수간의 비교에는 '=='를 사용할 수 있다. '=='로 비교가 가능하기에 빠른 성능을 제공한다.

  • 열거형 상수는 비교연산자(' < ', ' > ')는 사용할 수 없고, compareTo( )는 사용이 가능하다.

모든 열거형의 조상 - java.lang.Enum

  • 모든 열거형의 조상은 java.lang.Enum이다.

  • 모든 열거형의 조상인 Enum은 아래와 같은 메서드가 정의되어 있다.

  • 특이하게도, Enum은 컴파일러가 자동으로 추가해주는 메서드가 하나 더 있다.

열거형에 멤버 추가하기

  • 열거형 상수에 멤버를 추가하려면, 지정된 값을 저장할 수 있는 인스턴스 변수와 생성자를 새로 추가해야 한다.
  • 주의할 점은, 먼저 열거형 상수를 모두 정의한 다음에 다른 멤버들을 추가해야 한다.
// 열거형 상수에 멤버 추가 예제
enum Direction {
	EAST(1), SOUTH(5), WEST(-1), NORTH(10);	// 끝에 ';'를 추가해야 한다.
    
    private final int value;	// 정수를 저장할 필드(인스턴스 변수)를 추가
    Direction(int value) { this.value = value; } // 생성자를 추가
    
    public int getValue() { return value; }
   
}

💡 열거형의 인스턴스 변수는 반드시 final일 필요는 없다.

  • 열거형은 객체를 생성할 수 없다. 열거형의 생성자는 제어자가 묵시적으로 private이기 때문이다.
  • 하나의 열거형 상수에 여러 값을 지정할 수도 있다.
// 하나의 열거형 상수에 여러 값 지정예제
enum Direction {
	EAST(1, ">"), SOUTH(2, "V"), WEST(3, "<"), NORTH(4, "^");
    
    private final int value;
    private final String symbol;
    
    Direction(int value, String symbol) {  // 접근 제어자 private이 생략됨
    this.value = value;
    this.symbol = symbol;
}

public int getValue() { return value; }
public String getSymbol() { return symbol; }

열거형에 추상메서드 추가하기

  • 열거형에는 추상 메서드를 추가할 수 있다.
  • 열거형 상수들마다 추상 메서드를 다르게 구현할 수도 있다.
// 열거형에 추상메서드 추가 예제
enum Transportation {
	BUS(100) {
    	int fare(int distance) { return distance * BASIC_FARE; }
    },
    TRAIN(150) int fare(int distance) { return distance * BASIC_FARE; },
    SHIP(100) int fare(int distance) { return distance * BASIC_FARE; },
    AIRPLANE(300) int fare(int distance) { return distance * BASIC_FARE; };
    
    abstract int fare(int distance);		// 거리에 따른 요금을 계산하는 추상 메서드
    
    protected final int BASIC_FARE;			// protected로 해야 각 상수에서 접근이 가능하다.
    
    Transportation(int basicFare) {
    	BASIC_FARE = basicFare;
    }
    
    public int getBasicFare() { return BASIC_FARE; }
}

열거형의 이해

		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;
    }
}

💡 Direction 클래스의 static 상수들의 값은 객체의 주소이고, 이 값은 변하지 않으므로 '=='으로 비교가 가능하다.

출처 : 자바의 정석 3rd Edition(남궁성 저, 도우출판)

0개의 댓글