이동식 저장소

[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 classinterface는 누구나 자유롭게 상속받을 수 있어서, 내가 알고 있는 자식 클래스 외에 다른 자식 클래스가 얼마든지 추가될 수 있다. 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