この記事は、以下の「Kotlin Reference」日本語版を
元にしています。
#Kotlin Reference (日本語)
https://dogwood008.github.io/kotlin-web-site-ja/docs/reference/classes.html
###前書き
Kotlin初心者が、書いております。
ここが違う、もっとわかりやすく書いて欲しい等のご指摘いただけると助かります。
内容は、「Kotlin Reference + 調べて参考にした記事数点」 程度です。
##sealed classとは?
英語訳は、
sealed = 印を押した、封印された
そこから考えると
sealed class = 封印されたクラス
直訳だとヒドイので、マイルドにすると制限のあるクラス、、、
「継承を制限されているクラス」ということが言えそうです。
##sealed classの特徴
①「sealed修飾子」をクラス名の前に記述するとクラスを宣言できる。
sealedクラスはサブクラスを持つことができますが、
全てシールクラスの中にネストする必要がある。
②sealed classは、ある意味でenum(列挙型)クラスの拡張である。
enumクラスの値のセットも同じく制限されているが、
enum定数はシングルインスタンスとしてのみ存在するのに対し、
sealed classのサブクラスは、状態を保持できる複数のインスタンスをもつことができます。
③状態管理を簡単に表せる、
また状態に値を持たせられる。(enumではできない)
④When式で分岐する際に、全てのケースをカバー出来る。
参考例:
sealed class Expr {
class Const(val number: Double) : Expr()
class Sum(val e1: Expr, val e2: Expr) : Expr()
object NotANumber : Expr()
}
以下に、when式の分岐でelseが不要な例を挙げています。
これはシールクラスの主な利点の一つで、
「Exprクラス」は、「sealed class」として定義されており、
他の場所でそのサブクラスが定義されないことを保証します。
そのためwhen式の分岐で、すべての場合が考慮されていることを、
コンパイラは知っているので「else」が不要になります。
参考例:
fun eval(expr: Expr): Double = when(expr) {
is Expr.Const -> expr.number
is Expr.Sum -> eval(expr.e1) + eval(expr.e2)
Expr.NotANumber -> Double.NaN
// 全ての事例を嘗めたため、`else` 句は不要
}
メモ:
・インタフェースにはsealedを付けられないようです。
・この制限を緩和して同一ソースファイル内での継承も許可するそうです。(2019年8月28日現在:不可能 Kotlin1.3)
・使い方の参考例で2例ほど取り上げられていました。
https://blog.takuji31.jp/entry/2017/12/07/183613
「どういう使い方をしている?」で検索
参考:
Kotlin M13で追加されたsealed class
https://taro.hatenablog.jp/entry/2015/09/17/131439
KotlinのSealed Classを使いこなす
https://blog.takuji31.jp/entry/2017/12/07/183613
KotlinのSealed Classを学ぶ
https://qiita.com/ikemura23/items/c4555600bc512fb3e4cb
Kotlin文法 - クラス、継承、プロパティ
https://qiita.com/k5n/items/35e76d79ee9de4effb89#%E3%82%AF%E3%83%A9%E3%82%B9