본문 바로가기
안드로이드 프로그래밍/문법정리

[kotlin] 코틀린 enum class (열거 클래스)

by 1chanhue1 2024. 5. 28.

Enum class 

Enum class란 일반적으로 선언되는 상수와는 다르게, 여러 개의 값을 열거해서 사용할 수 있도록 정의해 놓은 클래스이다.

enum class Fruit
{
    GRAPE,
    APPLE,
    ORANGE,
    MANGO
}

일반적인 형태의 enum class는 위와 같은 형태로,
Fruit가 해당 클래스의 클래스 명이며, 블록 안에 순차적으로 콤마(,)를 통해 나열된 값이
해당 클래스의 인스턴스이다.
특별히 생성자를 정의하지 않는 경우 위에서부터 순차적으로 0,1,2,3...의 값이 부여된다.
각 enum 인스턴스는 일반적으로 name과 ordinal이라는 프로퍼티를 가지며,
name은 인스턴스의 이름을, ordinal은 인스턴스의 순서를 나타낸다.
위와 같이 선언된 enum class는 다음과 같이 사용될 수 있다.

val fruit = Fruit.GRAPE
fruit.name // "GRAPE"
fruit.ordinal // 0

0부터 시작하는 정수 값 이외에도 다른 값을 넣을 수도 있는데,이런 경우 별도의 생성자를 정의해주어야 한다.

enum class Fruit(price:Int,tag:String){
	GRAPE(3000,"grape"),
    APPLE(2000,"apple"),
    ORANGE(4000,"orange"),
    MANGO(10000,"mango")
}

생성자를 가진 enum 클래스의 인스턴스는 동일한 생성자로 값을 넣어야 하고,
같은 클래스 내에 동일한 값을 가진 인스턴스는 존재할 수 없음에 주의해야 한다.
이렇게 생성된 클래스는 다음과 같이 사용될 수 있다.

val fruit = Fruit.GRAPE
fruit.price // 3000
fruit.tag // "grape"

enum 클래스도 클래스이기에, 일반적인 클래스의 기능도 사용할 수 있다.
함수 및 프로퍼티도 추가할 수 있다.

enum class Fruit(price:Int,tag:String){
	GRAPE(3000,"grape"),
    APPLE(2000,"apple"),
    ORANGE(4000,"orange"),
    MANGO(10000,"mango");
    
    fun printName():String = "fruit name is $name"
    val tenPiecePrice
    	get() = price*10
}

 

어떻게 활용 할 수 있을까? 

 

필자는 enum class를 일반적으로 쓰이는 상수값을 변수처럼 이름을 붙여놓은 것처럼 생각한다.
특정 상수를 val 변수에 할당하여 이름붙여 사용하면 재사용성이 증가하고 관리포인트가 줄어들어 유지보수성이 편리해진다는 장점이 있다.그러한 상수가 여러개 생기게 되면 어떠한 상수가 있는지, 몇 개의 상수가 있는지 개발자의 기억력에 의존하게 된다는 문제가 있다.
상수를 여러 개 쓰다보면 각 상수마다 비슷한 용도 및 맥락에서 사용되는 경우가 있는데,
이러한 상수를 enum 클래스를 사용하여 묶어두면 로직 작성 및 유지보수하는 관점에서도 편리해진다.
그 중 하나가 when 조건문과 함께하는 경우인데,
when 문에서는 일반적으로 매번 else 문을 써줘야 하는 경우가 많다.
이러한 경우 enum 값을 사용하면 이러한 문제가 깔끔해진다.

val value:Fruit = Fruit.GRAPE
when(value){
	Fruit.GRAPE-> {...}
    Fruit.APPLE-> {...}
    Fruit.MANGO-> {...}
    Fruit.ORANGE-> {...}
}

위 문에서는 enum 클래스인 Fruit의 모든 인스턴스를 명시했기 때문에,
컴파일 시점에서 해당 값들의 한계를 명확히 알 수 없으므로,
따로 else 문을 써주지 않아도 된다.

 

이외에도 UI를 유지보수하기 편하게 하기 위해 State 패턴을 이용하는 경우가 있는데,
이러한 상태 객체를 정의하기 위해 enum class를 사용할 수 있다.

enum class UiState(){
	Success,
    Fail,
    Loading
}

fun handleState(state:UiState){
	when(state){
    	Success-> { ...}
        Fail -> { ...}
        Loading -> { ...}
    }
}

위와 같이 특정 Ui의 상태값을 받고서 State의 상태에 따라서 when문에 따라 분기하여
해당 값을 처리할 수 있도록 할 수도 있다.