Kotlin 열거형 클래스(Enum Classes)
열거형 클래스(enum class)
열겨형 클래스는 class
키워드 앞에 enum
를 붙여 선언한다.
각 열거형 상수는 객체이며, 열거형 상수는 쉼표로 구분된다.
enum class Direction {
NORTH, SOUTH, WEST, EAST
}
fun main() {
println(Direction.NORTH)
}
Output:
NORTH
각각의 Enum은 Enum class의 인스턴스 이므로 특정 값으로 초기화 될 수 있다.
enum class Color(val strRgb: String, val hexaRgb: Int) {
RED("#f00", 0xFF0000),
GREEN("#0f0", 0x00FF00),
BLUE("#00f",0x0000FF ),
}
fun main() {
println(Color.RED)
println(Color.RED.name)
println(Color.RED.strRgb)
println(Color.RED.hexaRgb.toString(16))
}
Output:
RED
RED
#f00
ff0000
enum 정의 형식
enum
키워드를 사용하여 열거체를 정의할 수 있다.- 정의된 열거체의 첫 번째 상수값은 0부터 설정되며, 그 다음은 바로 앞의 상수값보다 1만큼 증가되며 설정된다.
- 불규칙한 값을 상수값으로 설정하고 싶으면 상수의 이름 옆에 괄호(
()
)을 추가하고, 그 안에 원하는 정수로 된 상수값을 명시할 수 있다. - 열거체명 오른쪽에
val
로 변수를 선언하면 해당 열거형 요소의 상수값을 확인할 수 있다. 자료형 지정을 통해ordinal
타입을 지정할 수 있다.
enum을 사용하는 이유
- 인스턴스 생성과 상속을 방지, 상수값의 타입 안정성을 보장한다.
- 열거형 클래스의 가장 기본적인 사용 이유는 형식이 안전한 열거형(type-safe enums)을 구현하는 것이다.
- 코드가 단순해지고, 가독성이 높아진다.
익명의 클래스 (Anonymous Classes)
Enum constant는 자신의 anonymous class들과 method들을 선언할 수 있고, base method를 override 할 수 있다.
enum class ProtocolState {
WAITING {
override fun signal() = TALKING
},
TALKING {
override fun signal() = WAITING
};
abstract fun signal(): ProtocolState
}
fun main() {
println(ProtocolState.TALKING.signal())
println(ProtocolState.WAITING.signal())
}
Output:
WAITING
TALKING
Enum class에 멤버를 정의할때는, 멤버 정의와 enum constant 정의를 세미콜론(;
)으로 구분해야 한다.
Enum의 항목(entry)들은 중첩된 클래스를 가질 수 없다.
열겨형에서는의 인터페이스 구현 (Implementing Interfaces in Enum Classes)
enum class는 상속 대신 interface 를 사용한다.
interface는 모든 항목을 위한 하나의 인터페이스 멤버를 가지거나 anonymous class 안에 있는 각각의 항목을 위한 인터페이스들을 가진다.
import java.util.function.BinaryOperator
import java.util.function.IntBinaryOperator
enum class IntArithmetics : BinaryOperator<Int>, IntBinaryOperator {
PLUS {
override fun apply(t: Int, u: Int): Int = t + u
},
TIMES {
override fun apply(t: Int, u: Int): Int = t * u
};
override fun applyAsInt(t: Int, u: Int) = apply(t, u)
}
fun main() {
val t = 2
val u = 3
println("PLUS($t, $u) = ${IntArithmetics.PLUS.apply(t, u)}");
println("TIMES($t, $u) = ${IntArithmetics.TIMES.apply(t, u)}");
}
Output:
PLUS(2, 3) = 5
TIMES(2, 3) = 6
열거형 상수 작업 (Working with enum constants)
Enum class는 정의된 enum constant를 리스트를 받아올 수 있고, 열거형 이름으로 enum constant를 받아 올수 있는 Synthetic methods를 가진다.
이런 methods의 Signature 는 아래와 같다.
메소드 | 설명 |
---|---|
EnumClass.valueOf(value: String): EnumClass |
인자로 전달된 문자열과 일치하는 해당 열거체의 상수를 반환한다. |
EnumClass.values(): Array<EnumClass> |
해당 열거체의 모든 상수를 저장한 배열을 생성하여 반환한다. |
아래 예제에서는 열거형 클래스의 목록과 특정 열거형 데이터를 받아오고 있다.
fun main() {
println(Color.valueOf("RED").name)
println(Color.values().joinToString())
}
Output:
NORTH, SOUTH, WEST, EAST
NORTH
valueOf()
메소드는 일치하는 Enum constant가 없으면 IllegalArgumentException
를 발생시킨다.
enumValues<T>()
, enumValueOf<T>()
함수를 통해 generic 방식으로 enum class 의 constant에 접근할 수 있다.
enum class RGB { RED, GREEN, BLUE }
inline fun <reified T : Enum<T>> printAllValues() {
print(enumValues<T>().joinToString { it.name })
}
fun main() {
printAllValues<RGB>() // prints RED, GREEN, BLUE
}
Output:
RED, GREEN, BLUE
모든 enum constant는 enum 정의내에서의 자신의 이름(.name
)과 위치(.ordinal
)를 받아 올 수 있는 property를 가진다.
메소드 | 설명 |
---|---|
val name: String |
열거형의 이름을 반환한다. |
val ordinal: Int |
열거형의 인덱스를 반환한다. |
아래 예제에서는 이름과 위치를 받아오고 있다.
fun main() {
println(Color.RED.name)
println(Color.RED.ordinal)
}
Output:
RED
0