17
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

[Kotlin]sealed class(interface)の意義

Last updated at Posted at 2022-05-12

sealedマークを付けると

継承を制限することが出来ます。
sealed interface(class)のネストか同じファイル内でないと、継承させることはできません。

SportsStatus.kt
sealed interface Sports {
   object Soccer : Sports
   object Baseball : Sports
   object Tennis : Sports
}

上記の場合だと、Sportsの親クラスに対する子クラスは三つしかないことが確約されます。

fun playGame(status: Sports) = when(status) {
   is Soccer -> {}
   is Baseball -> {}
//   is Tennis -> {}    :考慮漏れがあるとコンパイルエラー
}

when式にかけた時に、考慮漏れがあるとコンパイルエラーにする機能があります。

Enumとの違い

自分は、だから何?という心持ちでした。
そもそも、状態の定義ならenumでいいじゃないかと。

enum class Sports(val player: String) {
   Soccer("messi")
   Baseball("ichiro")
   Tennis("osaka")
}

enumの特徴は、シングルトンであり、valuesによって全体検索を掛けられること。
サーバーからのレスポンスに対してパースするのに便利。

しかし、上記でTennisオブジェクトだけは値を持たない場合に不便です。
playerをnullableで定義して、nullをセットするのは違和感。

enum class Sports(player: String?) {
    Soccer("messi"),
    Baseball("ichiro"),
    Tennis(null)
}

そこで、sealed classで定義すれば、各子クラスに持たせたいデータを自由に定義することが出来る。
将来的に、データを持つ状態が増える可能性を考えるとsealed interface(class)で定義した方が無難な気がする。

sealed class Sports {
    data class Soccer(val player: String) : Sports()
    data class Baseball(val player: String) : Sports()
    object Tennis : Sports()
}

Sealed interfaceとSealed Classの使い分け

使い分けは、ケースバイケースなのかなぁという意見。
基本的に、sealed interfaceで書けるか試してみる。
要件的に、厳しかったらsealed classを検討してみます。

例えば、共通のフィールドやコンストラクタを持たせたい場合があるかなと思います。

17
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
17
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?