如何使用 Sealed Classes

如何使用 Sealed Classes

Sealed classes 是被用來限制繼承的類別,當有特定數量的型別,透過 Sealed classes 可以在 when 判斷的時候,不用額外判斷 else,因為 Sealed classes 已經知道所有型別,不會再有更多型別出現。

說明

假設現在有一個這樣的類別。

interface Expr
class Num(val value: Int) : Expr()
class Sum(val value: Int) : Expr()
fun eval(e: Expr): Int =
	when(e) {
    is Num -> e.value
    is Sum -> e.value
    else -> println("no case")
  }

可以看到透過 when 必須涵蓋所有的範圍,所以你必須列舉所有類別。

但是如果透過 sealed class 的話,就可以限縮範圍,將其設定在特別型別內,因此,當你使用 when 的時候,就不需要額外再寫入 else 的處理部分了。

sealed class Expr
class Num(val value: Int) : Expr()
class Sum(val value: Int) : Expr()
fun eval(e: Expr): Int =
	when(e) {
    is Num -> e.value
    is Sum -> e.value
  }

sealed class 是一個虛擬類別,因此你無法實體化它,如果你把 sealed class 反組譯看看。

sealed class MyClass {}

你會發現它就是一個 abstract class。

public abstract class MyClass {}

所以如果你要在裡面設定方法,該方法也必須是 abstract 的方法。

sealed class MyClass {
    abstract fun test()
}

sealed class 不允許宣告 public 的建構子,而且它預設是 private 的建構子,從以下結果可以看出來。

sealed class MyClass private constructor() {}
sealed class MyClass public constructor() {} //constructor must be private in sealed class

如果你要繼承 sealed class,那麼就無法再繼承其他類別了。

sealed class MyClass
abstract class AbstractClass
class subClass : MyClass(), AbstractClass() 

你就會看到 AbstractClass 這邊跳出錯誤訊息顯示 only one class may appear in a supertype list

參考資料

https://kotlinlang.org/docs/reference/sealed-classes.html