핵심 정리 1: 정수 열거 패턴의 단점

핵심 정리 2: 열거 타입(enum)의 장점

열거 타입 선언으로 만들어진 인스턴스는 싱글턴이다.

컴파일타임 타입 안전성을 제공한다.

public enum Apple {

    FUJI, PIPPIN, GRANNY_SMITH;

}

---

public class AppleClient {

    public static void main(String[] args) {
        FruitStore fruitStore = new FruitStore();
        System.out.println(fruitStore.getPrice(Apple.PIPPIN));
        // 이름 자체만으로도 return 이 가능하다. 
        **System.out.println(Apple.PIPPIN);**
    }
}

---

public class FruitStore {
		// 타입 안전성을 나타내지만 해당 처럼 코드를 쓰면 안됨 (본문)
    public int getPrice(**Apple apple**) {
        return switch (apple) {
            case FUJI -> 100;
            case PIPPIN -> 200;
            case GRANNY_SMITH -> 300;
        };
    }

    public int getPrice(Orange orange) {
        return switch (orange) {
            case NAVEL -> 150;
            case TEMPLE -> 250;
            case BLOOD -> 350;
        };
    }
}

열거 타입에 이름 공간을 있으니 (공간이 다른) 이름이 같은 상수도 공존할 수 있 다.

새로운 상수를 추가하거나 순서를 바꿔도 다시 컴파일 하지 않아도 된다.

toString 메서드는 출력하기 적절한 문자열을 제공한다.

핵심 정리 3: 열거 타입(enum)의 장점

메서드나 필드를 추가하고 인터페이스를 구현할 수도 있다.

public interface Fruit {

    int getPrice();

}

===

public enum Apple implements Fruit {

    FUJI(100), PIPPIN(120), GRANNY_SMITH(140);

    private int price;
		
		**// enum 의 생성자는 반드시 private
    Apple(int price) {
        this.price = price;
    }**

    @Override
    public int getPrice() {
        return this.price;
    }
}

===

public enum Orange implements Fruit {

    NAVEL(40), TEMPLE(35), BLOOD(20);

    private final int price;

    Orange(int price) {
        this.price = price;
    }

    @Override
    public int getPrice() {
        return this.price;
    }
}

==

public class FruitStore {

    **public int getPrice(Fruit fruit) {
        return fruit.getPrice();
    }**
}

values 메서드를 사용해 정의되어 있는 모든 상수 배열을 사용할 수 있다.

// 어떤 객체의 지구에서의 무게를 입력받아 여덟 행성에서의 무게를 출력한다. (212쪽)
public class WeightTable {
   public static void main(String[] args) {
      double earthWeight = 10;
      double mass = earthWeight / Planet.EARTH.surfaceGravity();
      Planet[] values = Planet.values();
      for (Planet p : values)
         System.out.printf("%s에서의 무게는 %f이다.%n", p, p.surfaceWeight(mass));
   }
}

===

// 코드 34-3 데이터와 메서드를 갖는 열거 타입 (211쪽)
public enum Planet {
    MERCURY(3.302e+23, 2.439e6),
    VENUS  (4.869e+24, 6.052e6),
    EARTH  (5.975e+24, 6.378e6),
    MARS   (6.419e+23, 3.393e6),
    JUPITER(1.899e+27, 7.149e7),
    SATURN (5.685e+26, 6.027e7),
    URANUS (8.683e+25, 2.556e7),
    NEPTUNE(1.024e+26, 2.477e7);

    private final double mass;           // 질량(단위: 킬로그램)
    private final double radius;         // 반지름(단위: 미터)
    private final double surfaceGravity; // 표면중력(단위: m / s^2)

    // 중력상수(단위: m^3 / kg s^2)
    private static final double G = 6.67300E-11;

    // 생성자
    Planet(double mass, double radius) {
        this.mass = mass;
        this.radius = radius;
        surfaceGravity = G * mass / (radius * radius);
    }

    public double mass()           { return mass; }
    public double radius()         { return radius; }
    public double surfaceGravity() { return surfaceGravity; }

    public double surfaceWeight(double mass) {
        return mass * surfaceGravity;  // F = ma
    }
}

열거 타입에서 상수를 제거한다면?

상수마다 동적아 달라져야 한다면?