본문 바로가기

Kotlin

Kotlin - Enum 클래스

 

https://kotlinlang.org/docs/enum-classes.html

 

Enum classes | Kotlin

 

kotlinlang.org

 

개별 enum 상수는 오브젝트이고 서로 콤마로 구분하여 작성한다. 각 enum 은 enum 클래스의 인스턴스 이기 때문에 아래 처럼 초기화 할 수 있다.

// 일반적인 enum 
enum class Direction {
    NORTH, SOUTH, WEST, EAST
}

// 속성값이 있는 경우 초기화
enum class Color(val rgb: Int) {
    RED(0xFF0000),
    GREEN(0x00FF00),
    BLUE(0x0000FF)
}

 

익명 클래스

enum 상수는 아래 처럼 자기 자신을 익명 클래스로 선언 할 수 있다. 그렇기 때문에 아래 처럼 enum 클래스의 함수를 오버라이딩 하는 것이 가능하다.

enum class ProtocolState {
    WAITING {
        override fun signal() = TALKING
    },
    TALKING {
        override fun signal() = WAITING
    }; // 세미 콜론을 붙여서 아래 멤버(abstract fun signal()...) 와 분리

    abstract fun signal(): ProtocolState
}

fun main() {
    println(ProtocolState.WAITING)
//    WAITING
    println(ProtocolState.WAITING.signal())
//    TALKING
}

 

enum 클래스로 인터페이스 구현하기

enum 클래스를 통해 인터페이스를 구현할 수 있고(클래스를 상속 받는 것은 불가능 하다.), enum 상수의 익명 클래스를 통해 인터페이스를 구현 할 수도있다.

enum 클래스에서 정의된 함수를 enum 상수에서 재 정의 하는 것도 가능하다.

아래 예제를 보자.

open class HelloEnum {
    open fun sayHello() {
        println("This is HelloEnum")
    }
}

// compile error - class는 상속 받을 수 없음
//enum class ChildEnum: HelloEnum() {
//}

interface HelloInterface {
    fun sayHello()
}

enum class ChildEnum2: HelloInterface {
    A {
        override fun sayHello() {
            println("This is A")
        }
    },
    B {
        override fun sayHello2() {
            println("This is B")
        }
    },
    C;

    override fun sayHello() {
        println("This is Common")
        sayHello2()
    }

    open fun sayHello2() {
        println("This is Common2")
    }
}





fun main() {
    ChildEnum2.A.sayHello()
//    This is A

    ChildEnum2.B.sayHello()
//    This is Common
//    This is B

    ChildEnum2.C.sayHello()
//    This is Common
//    This is Common2
}

 

enum 상수

enum 클래스는 enum 상수의 목록 속성이나, enum 상수의 문자열 값으로 해당 상수를 찾는 함수 - entries, valueOf 를 가지고 있다.

    for (e in ChildEnum2.entries) {
        println("name : ${e.name}, ordinal : ${e.ordinal}")
    }
//    name : A, ordinal : 0
//    name : B, ordinal : 1
//    name : C, ordinal : 2

    val a = ChildEnum2.valueOf("A")
    println(a)
//    A
    val b = ChildEnum2.valueOf("B")
    println(b)
//    B

제네릭 함수인 enumValues<T> 함수와 enumValueOf<T> 함수를 이용해서 동일한 기능을 구현 할 수도 있다.

    for (e in enumValues<ChildEnum2>()) {
        println("name : ${e.name}, ordinal : ${e.ordinal}")
    }
//    name : A, ordinal : 0
//    name : B, ordinal : 1
//    name : C, ordinal : 2

    val a2 = enumValueOf<ChildEnum2>("A")
    println(a2)
//    A

 

코틀린 1.9.20 부터는 enumEntries<T> 함수가 추가되는데 enumValues<T>와 비슷 하지만 차이점이, enumValues 함수는 호출 할때마다 enum 상수 배열을 새로 생성하지만 enumEntries 함수는 매번 같은 배열을 반환한다. 따라서 더 효율적 이기 때문에 해당 함수가 추가 된 이후에는 enumEntries 함수를 더 사용 하는 것이 좋다.

반응형