본문 바로가기
Android & Kotlin/Kotlin

[Kotlin] 코틀린 Sealed class ,Interface

by 말린밴댕이_공부 2024. 5. 3.
반응형

Sealed Class : 클래스 계층 정의 시 계층 확장 제한

추상 클래스의 하나로써 자식 클래스의 종류를 제한하는 특성을 가지고 있음

 

interface Expr

class Num(val value: Int) : Expr
class Sum(val left: Int, val right: Int) : Expr

fun eval(e: Expr): Int = when (e) {
    is Num -> e.value
    is Sum -> e.left + e.right
    else -> throw IllegalArgumentException("Unknown Expression")
}

위의 보게 되면 when식에서 EXPR의 모든 하위 클래스를 처리하는데 else 분기를 반드시 넣어줘야한다.

 

디폴트 분기인 else분기를 강제하며 클래스 계층에 새로운 하위 클래스를 추가하더라도 컴파일러다 when이 모든 경우를 처리하는지 제대로 검사할 수 없다.

 

혹여나 새로운 클래스 처리를 잊어버렸더라도 default분기가 선택되기 때문에 심각한 버그가 발생할 수 있다.

이러한 경우 sealed class를 이용하면 굉장히 좋다.

 

sealed class를 통해 상위 클래스를 상혹한 하위 클래스 정의를 제한할 수 있으며, 하위 클래스를 정의 때는 반드시 상위 클래스 안에 중첩시켜야한다.

sealed class Expr {
    class Num(val value: Int) : Expr()
    class Sum(val left, val right: Int) : Expr()
}

fun eval(e: Expr): Int = when (e) {
    is Expr.Num -> e.value
    is Expr.Sum -> e.left + e.right
    //else -> else분기 쓸 필요가 없음!
}

디폴트 분기인 else 분기가 필요가 없어졌으며, sealed 클래스는 자동으로 open입니다.

 

 

안드로이드 sealed class 예시

//네트워크 통신 BaseState
sealed class BaseState<out T> {
    data class Success<out T>(val data: T) : BaseState<T>()
    data class Error(val statusCode: StatusCode, val message: String) : BaseState<Nothing>()
}

BaseState의 sealed class와 두개의 하위 클래스인 Success, Error가 있습니다.

 

네트워크 통신

성공 시 반환되는 데이터를 제너릭 타입을 파라미터로 가지며 반환되며,

실패 시 statuscode와 message를 파라미터로 가집니다.

 

 

Sealed Interface

하나의 sealed class 만 상속하는 계층적 한계를 극복하기 위해 추가되었으며 다중 상속을 통한 다형성을 부여할 수 있으며 코틀린 1.5부터 추가가 되었습니다.

sealed interface Error

sealed class IOError(): Error

class FileReadError(val file: File): IOError()
class DatabaseError(val source: DataSource): IOError()

object RuntimeError : Error

*Reference : Kotlin Sealed class, interface 공식문서 *

반응형

댓글