열거 타입
일정 개수의 상수 값을 정의한 다음, 그 외의 값은 허용하지 않는 타입
예시) 사계절, 태양계의 행성, 카드게임의 카드 종류
public static final int APPLE_FUJI = 0;
public static final int APPLE_PIPPIN = 1;
public static final int APPLE_GRANNY_SMITH = 2;
public static final int ORANGE_NAVEL = 0;
public static final int ORANGE_TEMPLE = 1;
public static final int ORANGE_BLOOD = 2;
// 가장 단순한 열거타입
public enum Apple { FUJI, PIPIN, GRANNY_SMITH }
public enum Orange { NAVEL, TEMPLE, BLOOD }
예시 1. Apple, Orange의 경우 과일의 색을 알려주거나 이미지를 반환하는 메서드
예시 2. 태양계, 각 행성의 질량과 반지름을 통해 표면중력을 계산 할 수 있다. 따라서 어떤 객체의 질량이 주어지면 그 객체가 행성 표면에 있을 때의 무게도 계산할 수 있다.
//데이터와 메서드를 갖는 열거 타입
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.447e7);
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;
this.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
}
}
//상수별 메서드 구현을 활용한 열거 타입
public enum Operation {
PLUS { public double apply(double x, double y) { return x + y; } },
MINUS { public double apply(double x, double y) { return x - y; } },
TIMES { public double apply(double x, double y) { return x * y; } },
DIVIDE { public double apply(double x, double y) { return x / y; } };
public abstract double apply(double x, double y);
}
toString이 반환하는 문자열을 해당 열거 타입 상수로 변환해준다
Opitonal<Operation>
을 반환한다.
열거 타입 안에서 값에 따라 분기하는 건 좋지 않다
private 중첩 열거 타입을 통해 해결한다.
public enum PayrollDay {
MONDAY(WEEKDAY), TUESDAY(WEEKDAY), WEDNESDAY(WEEKDAY), THURSDAY(WEEKDAY), FRIDAY(WEEKDAY),
SATURDAY(WEEKEND), SUNDAY(WEEKEND);
private final PayType payType;
PayrollDay(PayType payType) {
this.payType = payType;
}
// 전략 열거 타입
enum PayType {
WEEKDAY {
int overtimePay(int minutesWorked, int payRate) {
return minutesWorked <= MINS_PER_SHIFT ?
0 : (minutesWorked - MINS_PER_SHIFT) * payRate / 2;
}
},
WEEKEND {
int overtimePay(int minutesWorked, int payRate) {
return minutesWorked * payRate / 2;
}
};
abstract int overtimePay(int minutesWorked, int payRate);
private static final int MINS_PER_SHIFT = 8 * 60;
int pay(int minutesWorked, int payRate) {
int basePay = minutesWorked * payRate;
return basePay + overtimePay(minutesWorked,payRate);
}
}
}