Kotlin: Sealed Classes 的基礎使用

Ray Yuan Liou
3 min readJul 7, 2018
「把 Class 都裝起來!」 圖片來源: StackExchange biology 板

在表達一個元件的狀態時,可能第一個想到的會是 enum class 。而現在有了新的選擇—— sealed class 。它們倆的差別是: enum class 可以拿來簡單的判斷狀態,但不能傳遞變數;反之,sealed class 可以攜帶變數。

sealed class 是一個 abstract class ,本身並不能被 instantiate(實體化)。但可以透過繼承某個 sealed class ,限縮可能的類型。可以傳遞變數這種特性讓它可以作為進階版的 enum 使用,與 when語法配合後效果更佳。(這裡先假設讀者已經大致知道 when 語法的用法)

先前情提要,一般在 Kotlin 中,也能使用 enum class 表達某一狀態該做什麼:

上面的範例印出目前的 machineState 為:

current state = Machine is sleeping

如果使用 sealed class ,可以將變數也一併傳遞。這在許多場合非常有用,例如控制一個 UI 元件的狀態常有幾種情境:讀取中、資料處理好可以顯示、資料是空的、出錯了⋯ 等幾種狀態。透過 sealed class ,使用起來可以更方便。
當然,如果不需要傳遞變數,也能單純建立許多 object ,這樣用起來與 enum class 就會是一樣的感覺。在 when 判斷式之中,如果某個 sealed class 子類別是 object ,便無需使用 is 來判斷。另外,如果已經判斷完所有的可能狀況(即判斷了所有的 sealed class 子類別), when 就不用另外處理 else 的情境。此外,sealed class 需要定義在同一個檔案裡頭。

以下範例以透過 Id 分別取得三台不同機器的 WorkingState,再由 machineStatePrinting() Function 印出不同狀態的結果:

三項結果分別是:

// result 01
the 1 result is Warthog
the 2 result is Hedgehog
the 3 result is Badger
the 4 result is Drake
// result 02
Error Occurred: reason is
Too big too eat.
// result 03
It's empty result.

另外補充,以上面的範例例子來舉例說明。假設執行 machineStatePrinting(workingState) 時傳入的變數是 WorkingState.Finished(val result: List<String>) ,在 when 判斷式之中 Kotlin 會自動做 Smart cast ,所以存取 workingState 時,不用自行手動轉換型別即可以取得變數 result

這裡介紹的只是一些常見的使用方式,不過卻可以套入許多情境,例如上面提到的 UI 元件的控制,或是網路 Request 的狀態⋯ 等需要判斷狀態的需求。配合 when判斷式使用,加上 Smart cast 減少一道轉換型別的手續,實在滿好用的。

補充資料

Kotlin Document: Sealed Classes

--

--