Sealed Class
sealed 클래스는 기본적으로 abstract 클래스이며 sealed 클래스를 상속받는 여러 서브 클래스들을 가질 수 있다.
sealed 클래스를 사용하면 보다 엄격하게 상속을 관리할 수 있다. 컴파일 시 컴파일러가 sealed 클래스를 상속받는 서브 클래스들을 모두 파악하고 있기 때문이다. 또한 컴파일 이후에는 서드파티 클라이언트가 sealed 클래스를 확장할 수 없다.
서브 클래스는 class, data class, object 모두 가능하다. 다만 상태 값이 바뀌지 않는 서브 클래스라면 object를 사용하는 것이 좋다.

Sealed Class의 특성
- sealed 클래스의 서브 클래스들은 반드시 같은 파일 내에 선언되어야 한다.
- sealed 클래스는 기본적으로 abstract 클래스이며 인스턴스화 될 수 없다.
- sealed 클래스는 protected나 private 생성자만 갖는다.
적용
DSL 스터디 미션을 구현하면서 Sealed Class를 적용해보았다.
// Skill.kt
interface Skill
// HardSkill.kt
data class HardSkill(val value: String) : Skill
// SoftSkill.kt
data class SoftSkill(val value: String) : Skill
기존에는 interface를 사용하여 HardSkill과 SoftSkill를 각각의 data class 파일로 구현했다.
// Skill.kt
sealed class Skill
data class SoftSkill(val value: String) : Skill()
data class HardSkill(val value: String) : Skill()
리팩토링을 진행하며 Skill을 interface에서 sealed 클래스로 변경하였고, SoftSkill과 HardSkill을 같은 파일로 모았다.
여러 클래스를 한 파일에 넣는 것을 주저해서는 안 된다.
특히 각 클래스를 정의하는 소스코드 크기가 아주 작은 경우 더욱 그렇다.
(Kotlin In Action - p.77)
처음엔 여러 클래스를 한 파일에 넣는 것이 어색했는데 ‘Kotlin In Action’을 읽으면서 코틀린에서는 이게 어색한 일이 아니구나, 적절히 잘 사용해야겠다고 생각했다.
특히 when 절을 사용할 때 sealed 클래스의 특징을 잘 확인할 수 있다. sealed 클래스를 사용하지 않는 경우 컴파일러가 sealed 클래스의 서브 클래스들을 알지 못하기 때문에 반드시 else 절이 필요하다.
fun getSkillMessage(skill: Skill): String {
return when (skill) {
is SoftSkill -> "soft skill"
is HardSkill -> "hard skill"
else -> "no skill"
}
}
이 경우 두 가지 문제점이 생길 수 있다.
- else 절이 없으면 컴파일 에러가 발생한다.
- 서브 클래스 중 하나를 빠트려도 컴파일 에러가 발생하지 않는다.
sealed 클래스를 사용하면 컴파일러가 sealed 클래스의 서브 클래스들을 알 수 있기 때문에 위 두 가지 문제점을 모두 해결할 수 있다.
fun getSkillMessage(skill: Skill): String {
return when (skill) {
is SoftSkill -> "soft skill"
is HardSkill -> "hard skill"
}
}
else 절이 없어도 컴파일 에러가 발생하지 않으며, 서브 클래스 중 하나라도 처리를 빠트리는 경우 컴파일 에러가 발생하여 문제를 바로 파악할 수 있다.
Enum과의 차이
enum도 값들을 제한한다는 점에서 비슷한 점이 있지만, enum의 경우 싱글톤으로 존재한다는 점에서 차이가 있다. 또한 enum 클래스와 달리 상속을 지원하기 때문에, 상속을 활용한 풍부한 동작을 구현할 수 있다.
references
'코틀린' 카테고리의 다른 글
[Kotlin] Backing Field와 Backing Properties (wordle 미션) (2) | 2022.06.01 |
---|---|
[Kotlin] mutable collection 사용 줄이기 (wordle 미션) (7) | 2022.05.31 |
[Kotlin] 확장함수 (wordle 미션) (0) | 2022.05.31 |