개요
프로젝트를 진행하면서 Type을 일반 정수형이 아닌 알기 편하게 하기 위해 주로 enum class로 정의해왔었는데,
얘를들어 선수, 심판, 감독에 대한 Type을 나누려고 할때
enum class Type{
player, referee, coach
}
이런식으로 나눴던 기억이 있는데 이번에 enum class에 대한 내용을 한번 정리해보려고 한다.
1. Enum 클래스란?
Enum(열거형) 클래스는 상수(constant) 집합을 표현하는 특수한 클래스이다.
상수를 하나의 타입으로 정의해 코드의 가독성을 높이고, 실수를 방지할 수 있다.
enum class Day {
MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY
}
여기서 각각의 요소들(= MONDAY, TUESDAY ...)는 자동으로 Day 타입의 객체로 생성된다.
객체로 생성된다니까 각각의 요소들은 기본적인 프로퍼티를 가지는데 다음과 같다.
: name
-> 해당 enum 요소의 이름(= MONDAY, THURSDAY...)
: ordinal
-> 해당 요소의 0부터 시작하는 인덱스(순서)
-> Monday = 0, TUESDAY = 1 요런 느낌?
fun main() {
val today = Day.WEDNESDAY
println(today.name)
println(today.ordinal)
}
// 출력
// WEDNESDAY
// 2
1-1. 프로퍼티
Enum 클래스의 요소는 위에서 언급했다시피, 단순 상수가 아니라 객체이기 때문에 프로퍼티와 메서드를 추가할 수 있다.
enum class Day(val isWeekend: Boolean) {
MONDAY(false),
TUESDAY(false),
WEDNESDAY(false),
THURSDAY(false),
FRIDAY(false),
SATURDAY(true),
SUNDAY(true);
}
fun main() {
println(Day.SATURDAY.isWeekend)
}
//출력
//false
-> 각 요소들이 isWeekend라는 프로퍼티를 가지고, 생성자를 통해 값을 초기화한다.
-> 위에 처럼 생성자가 필요한 경우에는 마지막 요소 끝에 세미콜론(;)을 추가해야 한다.
1-2. 기본 메서드
기본적으로 사용되는 메서드가 있는데, 다음과 같다.
: values() : Array<T>
-> 해당 Enum 클래스의 모든 요소를 배열로 반환한다.
fun main(){
val days = Day.values()
days.forEach { println(it) }
}
// 출력
// MONDAY
// TUESDAY
// ...
// SUNDAY
: valueOf(name : String)
-> 문자열을 Enum 요소로 변환하며, 존재하지 않는 이름을 입력하면 예외가 발생한다.
fun main() {
val day = Day.valueOf("FRIDAY")
println(day)
}
// 출력
// FRIDAY
1-3. 사용자 정의 메소드
각 요소들에 공통적으로 적용되는 메서드를 사용자가 직접 만들어서 사용할 수 있다.
enum class Day {
MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY;
fun isWeekend(): Boolean {
return this == SATURDAY || this == SUNDAY
}
}
fun main() {
println(Day.FRIDAY.isWeekend())
println(Day.SATURDAY.isWeekend())
}
// 출력
// false
// true
1-4. 추상 메소드
또한 Enum 클래스는 추상클래스이기 때문에, 추상메소드를 통해 각 요소마다 다르게 메소드를 정의할 수도 있다.
enum class Day {
MONDAY {
override fun getDailyMessage(): String = "월요일 좋아"
},
TUESDAY {
override fun getDailyMessage(): String = "화요일 좋아"
},
WEDNESDAY {
override fun getDailyMessage(): String = "수요일 좋아"
},
THURSDAY {
override fun getDailyMessage(): String = "목요일 좋아"
},
FRIDAY {
override fun getDailyMessage(): String = "금요일 좋아"
},
SATURDAY {
override fun getDailyMessage(): String = "토요일 좋아"
},
SUNDAY {
override fun getDailyMessage(): String = "일요일 좋아"
};
abstract fun getDailyMessage(): String
}
fun main() {
println(Day.MONDAY.getDailyMessage())
println(Day.SATURDAY.getDailyMessage())
}
// 출력
// 월요일 좋아
// 토요일 좋아
1-5. Companion Object
마찬가지로 enum class는 추상 클래스로 Companion Object를 사용해 정적 메서드를 추가할 수도 있다.
enum class Day {
MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY;
companion object {
fun fromString(name: String): Day? {
return entries.find { it.name.equals(name, ignoreCase = true) }
}
}
}
fun main() {
val day = Day.fromString("monday")
println(day) // MONDAY
}
// 출력
// MONDAY
* 참고
위의 코드에서 values()가 아니라 entries를 사용했다.
entries는 Kotlin 1.9부터 제공되는 List 타입 프로퍼티로, 코드에서 values()를 사용할 경우 entries로 바꿀 것을 권장한다.
권장하는 이유는 다음과 같다.
-> 기존 values() 메서드는 컴파일러가 자동 생성하는 static 메서드로, 호출할 때마다 새로운 배열을 생성해 반환한다.
-> 즉, values() 호출할 때마다 새로운 배열을 메모리에 할당해야 하기 때문에 메모리 낭비가 발생한다.
-> 반면, entries는 미리 생성된 리스트를 반환하고 호출할 때마다 동일한 리스트 객체를 재사용한다.
추후에 Sealed class 적으면서 enum class와의 차이에 대해 비교해보자
'Language > kotlin' 카테고리의 다른 글
[Kotlin] 접근 제한자(Visibility Modifier) (0) | 2025.02.13 |
---|---|
[Kotlin] Channel (3) | 2024.11.07 |
[Kotlin] StateFlow 및 SharedFlow (2) | 2024.10.07 |
[Kotlin] Flow - 소개 및 연산자 (8) | 2024.09.29 |
[Kotlin] 고차 함수와 람다 표현식 (1) | 2024.08.10 |