안드로이드

sealed class 란?

2023. 4. 2. 23:12

코틀린에는 다양한 클래스가 존재한다.

data class, object class, companion class, 등등..

 

그런데 최근 난생 처음보는 sealed class 라는 클래스가 보여 이에 대해 알아보았다.

 

결론부터 말하자면 sealed class 는 본인을 상속받은 자식 클래스가 어떤것들이 있는지 그 목록을 볼 수 있다.

(??? : 너 내가 주민등록등본 떼면 어디 사는지 다 나와~)

 

예를 들어보자면, 이렇게 간단한 abstract class 가 있다.

그리고 그 abstract class 를 상속받는 Running, Walking, Swimming 클래스를 선언하였다.

abstract class SealTestClass

class Running: SealTestClass()
class Walking: SealTestClass()
class Swimming: SealTestClass()

각 클래스에 따라 상태를 반환해주는 함수를 만들고 싶었는데,

fun getStateMessage(personState: SealTestClass): String {
    return when (personState) {
        is Running -> "뛰는중"
        is Walking -> "걷는중"
        is Swimming -> "수영하는중"
    }
}

이렇게 만들었더니 에러가 난다.

else 구문이 필요하다고 한다. 왜냐면 Running, Walking, Swimming 만 상속받았을지 얘가 어떻게 알겠냐는 거지.

SealTestClass 를 상속받은 다른 클래스가 더있을지 몰라 else 구문이 필요하다.

 

하지만 SealTestClass 를 sealed class 로 선언한다면?

sealed class SealTestClass

class Running: SealTestClass()
class Walking: SealTestClass()
class Swimming: SealTestClass()

 

에러가 발생하지 않는다.

이 때 Swimming 분기를 빼본다면?

Swimming 분기가 빠졌다고 친절하게 에러를 통해 알려준다.

 

sealed 클래스로 선언해 자식 클래스에 어떤 것들이 있는지 알 수 있게 되었기 때문이다.

 

이는 프로젝트의 크기가 커졌을 때 상태 관리에 굉장이 유리하게 사용될 수 있다.

 

abstract 클래스로 어떤 클래스를 선언하고 이를 상속받는 자식 클래스들이 다수 존재하고, 새로운 자식 클래스가 추가되었을 때 규모가 큰 프로젝트에서는 어디서 또 해당 자식 클래스를 추가해주어야 하는지 찾는것만으로도 시간이 걸릴 수 있고, 심지어는 특정 처리 로직에서 추가를 빼먹는 경우 또한 발생할 수 있다.

 

하지만 이런 상황에서 sealed 클래스로 선언되어 있다면, 어떤 자식 클래스에 대한 처리가 빠졌을 때 에러를 통해 알려주기 때문에 편리하게 코드를 관리할 수 있다.

 

* sealed 클래스는 코틀린에 존재하며, 유사한 기능을 swift 에서 사용하기 위해선 enum 을 사용해야 한다. (아래 링크 참고)

https://medium.com/xorum-io/how-to-mimic-kotlins-sealed-class-in-swift-17b1fc839bd4