티스토리 뷰

반응형

Kotlin의 sealed class

Kotlin에서 Sealed class는 enum class와 비슷한 특징을 가지고 있지만, 더 많은 기능을 제공합니다. Sealed class를 사용하면 상속 관계를 표현할 수 있으며, 각 하위 클래스마다 고유한 동작을 수행할 수 있습니다. sealed class는 다음과 같이 선언할 수 있습니다.

sealed class Color {
    object Red : Color()
    object Green : Color()
    object Blue : Color()
}

 

위 예제에서 Color는 sealed class로 선언되어 있습니다. sealed class는 자신의 하위 클래스를 가질 수 있으며, 하위 클래스는 sealed class 내부 혹은 외부에 중첩 클래스, 데이터 클래스, 열거형, object 등의 형태로 선언할 수 있습니다. Kotlin 1.5.0 이전까지는 sealed class의 하위 클래스는 모두 같은 파일 내부에서 선언되어야 했지만, 1.5.0에서 해당 파일 외부에서도 상속 받을 수 있도록 변경되었습니다.

 

이에 대한 것은 아래 두개 페이지에서 확인이 가능합니다.

 

Sealed interfaces and more sealed classes freedom : KT-42433

May 2021 1.5.0 includes support for [sealed interfaces](https://kotlinlang.org/docs/whatsnew15.html#sealed-interfaces) and [wider sealed class hierarchies](https://kotlinlang.org/docs/whatsnew15.html#package-wide-sealed-class-hierarchies) October 2020 Kotl

youtrack.jetbrains.com

 

 

What's new in Kotlin 1.5.0 | Kotlin

 

kotlinlang.org

 

Android에서 sealed class 사용 예제

안드로이드에서 Sealed class를 사용한 예제로는 네트워크 API 통신 결과 처리가 있습니다. 아래는 API 요청 결과를 처리하는 sealed class 예시 코드입니다.

sealed class NetworkResult<out T> {
    data class Success<out T>(val data: T) : NetworkResult<T>()
    data class Error(val exception: Exception) : NetworkResult<Nothing>()
    object Loading : NetworkResult<Nothing>()
}

위 코드는 NetworkResult 라는 sealed class를 선언하고, Success, Error, Loading 클래스를 내부 클래스로 선언하고 있습니다. Success 클래스는 NetworkResult 클래스를 상속하며, data 필드를 가지고 있습니다. Error 클래스는 NetworkResult 클래스를 상속하지만, data 필드는 없으며, exception 필드를 가지고 있습니다. Loading 클래스는 NetworkResult 클래스를 상속하지 않고, 데이터 필드를 가지지 않습니다.

 

위 코드를 사용하여 API 결과를 처리하는 함수를 아래와 같이 만들 수 있습니다.

fun <T> handleNetworkResult(result: NetworkResult<T>): T? {
    return when (result) {
        is NetworkResult.Success -> result.data
        is NetworkResult.Error -> null
        NetworkResult.Loading -> null
    }
}

이 함수는 handleNetworkResult라는 이름을 가진 제네릭 함수입니다. 이 함수는 인자로 NetworkResult를 받아들이며, 이는 sealed class의 세 가지 서브클래스(Success, Error, Loading) 중 하나일 수 있습니다.

 

when 식을 사용하여 서브클래스 타입별로 처리를 하며, Success 타입이면 데이터를 반환하고, Error 타입이면 null을 반환하게 됩니다. 마지막으로 Loading 타입이면 null을 반환하게 됩니다. 만약 Error나 Loading에 처리가 필요하다면 해당 블록에 별도 처리를 넣으면 됩니다.

 

이렇게 handleNetworkResult 함수를 사용하면, API 결과를 쉽게 처리할 수 있습니다. 예를 들어, 다음과 같이 사용할 수 있습니다.

val result: NetworkResult<User> = apiService.getUser(userId)
val user = handleNetworkResult(result)

getUser 함수가 NetworkResult<User> 타입으로 결과를 반환하므로, handleNetworkResult 함수를 사용하여 쉽게 처리할 수 있습니다. 이렇게 하면 코드가 간결해지며, 유지보수성이 높아집니다.

 

자 이제 사용 예제를 알아보았으니 sealed class의 특징에 대해 알아보겠습니다.

 

 

sealed class의 특징

 

sealed class는 다음과 같은 특징을 가지고 있습니다.

 

1. 상속 가능

sealed class는 상속이 가능합니다. 하위 클래스를 추가하는 경우, sealed class의 내부 혹은 외부에 선언된 클래스에서 모두 가능합니다. 컴파일러는 어느 곳에서 sealed class가 상속 받던 하위 타입을 모두 인식합니다.

 

2. 클래스 객체 생성 불가

sealed class는 객체를 생성할 수 없습니다. 따라서, sealed class는 추상 클래스와 같은 역할을 합니다. 하위 클래스는 object 형태로만 선언할 수 있으며, 생성된 하위 클래스의 인스턴스를 사용합니다.

 

 

sealed class의 특징

Kotlin에서 sealed class를 사용하면 다양한 장점을 누릴 수 있습니다.

 

안정성 보장

sealed class는 클래스 계층 구조를 정의할 때 사용됩니다. 이를 사용하면 상속 가능한 클래스의 종류를 제한할 수 있기 때문에, 안정적인 코드를 작성할 수 있습니다. sealed class는 자신이 포함된 파일 안에서만 상속이 가능하므로, 다른 클래스가 sealed class를 상속하더라도 파일 내부에서 정의된 클래스만을 상속할 수 있습니다. 이를 통해 안정적인 코드를 유지할 수 있습니다.

코드 중복 방지

sealed class를 사용하면 상속 가능한 클래스의 종류를 제한할 수 있습니다. 이를 통해 상속 가능한 클래스의 종류를 사전에 정의하고 관리할 수 있으며, 이를 통해 코드 중복을 방지할 수 있습니다.

 

패턴 매칭(Pattern Matching)을 강화

sealed class는 패턴 매칭을 강화하는 데에도 사용됩니다. 패턴 매칭은 코드를 작성할 때 런타임 오류를 방지할 수 있는 강력한 도구입니다. sealed class는 자신의 하위 클래스에 대한 패턴 매칭을 제공하기 때문에, 코드의 안정성을 높일 수 있습니다.

 

다형성 활용

sealed class는 추상 클래스와 비슷한 역할을 합니다. 하지만 sealed class는 상속 가능한 클래스의 종류를 제한할 수 있기 때문에, 다형성을 활용하는 데에 더욱 적합합니다. 이를 통해 유연하면서도 안정적인 코드를 작성할 수 있습니다.

 

코드의 가독성 향상

sealed class를 사용하면 상속 가능한 클래스의 종류를 사전에 정의하고 관리할 수 있기 때문에, 코드의 가독성을 높일 수 있습니다. sealed class는 여러 하위 클래스를 포함할 수 있기 때문에, 하위 클래스가 어떤 종류의 객체를 나타내는지 쉽게 파악할 수 있습니다.

Kotlin에서 sealed class는 다양한 장점을 가지고 있습니다. 이를 통해 안정적이고 유연하며 가독성이 높은 코드를 작성할 수 있습니다.

 

정리하며

sealed class는 Kotlin의 가장 강력한 기능중 하나입니다. sealed class의 장점을 잘 이해해서 쓰면 매우 안정성 높은 코드를 작성할 수 있습니다.

 

반응형
댓글