이동식 저장소

[Kotlin] sealed class 본문

Primary/Kotlin

[Kotlin] sealed class

해스끼 2022. 5. 20. 15:43

가위바위보에서 낼 수 있는 선택지는 가위, 바위, 보 3개뿐이다. 따라서 가위바위보의 참가자들은 다른 선택지를 내지 말아야 한다. 현실에서는 상대방의 강력한 항의와 눈초리를 통해 제한되지만, 프로그래밍에서도 그렇게 강제할 수 있을까?

interface RSPOption
class Rock: RSPOption
class Scissors: RSPOption
class Paper: RSPOption

// 이건 반칙이다
class Gun: RSPOption

짖궂은 개발자가 가위바위보에 ``Gun``을 추가하지 못하도록 막을 수 있는 방법이 없을까?

있으니까 글을 썼겠지?

sealed class

Kotlin의 sealed class를 사용하면 외부 개발자가 상속할 수 없는 상위 타입을 만들 수 있다.

sealed class RSPOption {
    class Rock: RSPOption()
    class Scissors: RSPOption()
    class Paper: RSPOption()
}

// 다른 파일에서는 RSPOption을 상속받을

sealed class는 클래스가 정의된 파일에서만 상속받을 수 있다. 위에서는 ``RSPOption`` 안에 모든 하위 클래스를 정의했지만, 같은 파일 안에서는 어디서든 상속할 수 있다.

 

final class는 절대로 상속될 수 없는 반면 sealed class는 파일 내에서만 상속될 수 있다는 차이점이 있다.

when에 안성맞춤

sealed class는 외부에서 상속받을 수 없는 특성상 자식 클래스가 컴파일 시간에 정해진다. 그래서 다음과 같은 코드를 짤 수 있다.

fun print(option: RSPOption) = when(option) {
    RSPOption.Rock -> println("Rock!")
    RSPOption.Scissors -> println("Scissors!")
    RSPOption.Paper -> println("Paper!")
}

``else`` 구문이 없다는 점에 주목해야 한다. 일반적인 ``open class``나 ``interface``는 누구나 자유롭게 상속받을 수 있어서, 내가 알고 있는 자식 클래스 외에 다른 자식 클래스가 얼마든지 추가될 수 있다. Kotlin은 이런 경우를 대비하여 ``when`` 문에 ``else``를 반드시 추가하도록 강제하고 있다.

 

그러나 sealed class를 사용하고 ``when``에서 모든 자식 클래스를 처리하는 분기를 작성했다면 ``else``문을 작성하지 않아도 된다. 

 

또, sealed class의 새로운 자식 클래스가 추가되었다면 ``when`` 구문에 새로운 분기를 추가가해야만 한다. 컴파일 에러 때문에 하기 싫어도 해야 한다. 수정이 필요한 부분을 콕 집어 주는 고마운 기능이다.

'Primary > Kotlin' 카테고리의 다른 글

[Kotlin] &&와 and의 차이  (0) 2022.06.03
[Kotlin] for? forEach?  (0) 2022.05.25
[Kotlin] Nested Class, Inner Class  (0) 2022.05.19
[Kotlin] abstract class  (0) 2022.05.18
[Kotlin] Inline class  (0) 2022.05.04
Comments