Enum은 열거형이라 불리며, 서로 연관된 상수들의 집합이다.
// fruit
const val APPLE = 1
const val PEACH = 2
const val BANANA = 3
// company
// const val APPLE = 1
const val GOOGLE =2
const val NAVER = 3
fun main() {
val type = APPLE
when (type) {
APPLE -> println("사과")
PEACH -> println("복숭아")
BANANA -> println("바나나")
}
}
-> 상수가 늘어날수록 가독성이 떨어지고, 각각의 상수 집합에서 같은 이름으로 정의된 상수가 있다면 중복된 이름이기 때문에 컴파일 단계에서 오류가 발생한다.
// fruit
interface FRUIT{
int APPLE = 1, PEACH =2, BANANA =3;
}
interface COMPANY{
int APPLE = 1, GOOGLE = 2, NAVER = 3;
}
public class EnumExample{
public static void main(String[] args) {
int type = COMPANY.APPLE;
switch(type) {
case FRUIT.APPLE:
System.out.println("사과");
break;
case FRUIT.PEACH:
System.out.println("복숭아");
break;
case FRUIT.BANANA:
System.out.println("바나나");
break;
}
}
}
-> FRUIT.APPLE
과 COMPANY.APPLE
모두 값이 정수 1이기 때문에 type이 COMPANY.APPLE
임에도 에러를 발생시키지 않고 사과를 출력해주고 있다. 이렇게 코드를 구현하게 되면 런타임 단계에서 예기치 못한 문제를 마주치게 된다.
class Fruit{
public static final Fruit APPLE = new Fruit();
public static final Fruit PEACH = new Fruit();
public static final Fruit BANANA = new Fruit();
}
class Company{
public static final Company GOOGLE = new Company();
public static final Company APPLE = new Company();
public static final Company ORACLE = new Company();
}
public class EnumExample {
public static void main(String[] args) {
if(Fruit.APPLE == Company.APPLE){
System.out.println("type이 같다.");
}
// 컴파일 오류 발생
}
}
-> 서로 다른 타입의 상수에 대해서는 비교를 금지시키지만 switch문에서 사용할 수 없고 선언이 너무 복잡하다는 문제점이 있다.
enum Fruit{
APPLE, PEACH, BANANA;
}
// 열거형을 사용하게 되면 다음과 같이 간단히 사용할 수 있다.
// 위의 코드는 아래코드와 사실상 같다.
class Fruit{
public static final Fruit APPLE = new Fruit();
public static final Fruit PEACH = new Fruit();
public static final Fruit BANANA = new Fruit();
private Fruit(){}
}
// fruit
enum class Fruit {
APPLE, PEACH, BANANA
}
// company
enum class Company {
APPLE, GOOGLE, NAVER
}
fun main() {
/*
if(Fruit.APPLE == Company.APPLE){
println("type이 같다.")
} // 컴파일 오류 발생
*/
val type = Fruit.APPLE
when (type) {
Fruit.APPLE ->
println("사과")
Fruit.PEACH ->
println("복숭아")
Fruit.BANANA ->
println("바나나")
}
}
enum에서도 일반적인 클래스와 마찬가지로 생성자와 프로퍼티를 선언한다. enum 클래스 안에 메소드를 정의하는 경우 반드시 enum 상수 목록과 메소드 정의 사이에 세미콜론(;)을 넣어야 한다.
enum class Color(val r: Int, val g: Int, val b: Int) { // 상수의 프로퍼티를 정의한다.
RED(255, 0, 0),
GREEN(0, 255, 0),
BLUE(0, 0, 255); // 메소드 구분을 위해 세미콜론 사용
fun rgb() = (r * 256 + g) * 256 + b
}
fun main() {
println(Color.GREEN.rgb())
}