sealed class และ sealed interface ใน Kotlin เป็นกลไกของลำดับชั้นประเภทแบบจำกัด ซึ่งคลาสย่อยที่เป็นไปได้ทั้งหมดจะถูกรู้จักในเวลาคอมไพล์ ต่างจากคลาสนามธรรมทั่วไป sealed class รับประกันการจัดการที่ครอบคลุมทุกตัวแปรในนิพจน์ when ตามเอกสาร JetBrains Kotlin Language Guide (2026) ประเภท sealed เป็นพื้นฐานสำหรับการจำลองสถานะ หน้าจอ UI และประเภทผลลัพธ์ในโปรเจกต์ Kotlin
ประเด็นสำคัญ
sealed class คือคลาสนามธรรมที่มีข้อจำกัด: คลาสย่อยโดยตรงทั้งหมดต้องถูกประกาศในไฟล์เดียวกับ sealed class เอง ข้อจำกัดนี้ทำให้ลำดับชั้นปิด (sealed) — ไม่มีโค้ดภายนอกไฟล์สามารถเพิ่มคลาสย่อยใหม่ได้
sealed interface ซึ่งเพิ่มใน Kotlin 1.5 ให้การรับประกันเดียวกันแต่ด้วยความยืดหยุ่นของอินเทอร์เฟส: sealed interface สามารถถูกนำไปใช้โดยคลาส วัตถุ หรืออินเทอร์เฟสอื่น ๆ หลายตัวในไฟล์เดียว ต่างจาก sealed class ตรงที่ sealed interface ไม่มีข้อจำกัดการสืบทอดเดี่ยว — คลาสหนึ่งสามารถ implement หลาย sealed interface พร้อมกันได้
ตาม Kotlin Evolution and Roadmap (2026) sealed interface ถูกเพิ่มตามคำขอของชุมชนเพื่อการจำลองที่ยืดหยุ่นมากขึ้น แรงจูงใจหลักคือความสามารถในการรวมลำดับชั้นประเภทอิสระโดยไม่ต้องมีการสืบทอดหลายคลาส
การประกาศ sealed class เริ่มต้นด้วยตัวปรับแต่ง sealed ก่อน class คลาสย่อยถูกประกาศในไฟล์เดียวกัน
sealed class NetworkResult {
data class Success(val data: String) : NetworkResult()
data class Error(val message: String) : NetworkResult()
object Loading : NetworkResult()
}
แต่ละคลาสย่อยของ sealed class สามารถมีคุณสมบัติและเมธอดของตัวเอง Loading เป็นซิงเกิลตัน (object) Success และ Error เป็น data class ที่มีพารามิเตอร์ คอมไพเลอร์รู้จักทั้งสามตัวแปรและตรวจสอบความสมบูรณ์เมื่อใช้ใน when
คลาส sealed สามารถซ้อนกันได้ สร้างลำดับชั้นหลายระดับสำหรับโมเดลข้อมูลที่ซับซ้อนโดยไม่สูญเสียความปลอดภัยของประเภท
sealed class UiState {
object Idle : UiState()
object Loading : UiState()
data class Content(val items: List<Item>) : UiState()
data class Error(val exception: Throwable) : UiState()
}
sealed interface ถูกประกาศคล้ายกับ sealed class แต่อนุญาตให้ implement หลาย sealed interface ในคลาสเดียว
sealed interface Action
sealed interface Loggable
data class Navigate(val route: String) : Action, Loggable
data class ShowToast(val text: String) : Action
object GoBack : Action, Loggable
คลาส Navigate implement สอง sealed interface พร้อมกัน — Action และ Loggable สิ่งนี้เป็นไปไม่ได้กับ sealed class เนื่องจากข้อจำกัดการสืบทอดเดี่ยว sealed interface ให้ความยืดหยุ่นในการรวมลำดับชั้นอิสระ
sealed interface เหมาะสมกว่าเมื่อลำดับชั้นไม่ต้องการสถานะหรือคอนสตรัคเตอร์ร่วม ตาม JetBrains Kotlin Guidelines (2026) ควรใช้ sealed interface เป็นค่าเริ่มต้นสำหรับลำดับชั้นใหม่ทั้งหมดที่ไม่ต้องการคอนสตรัคเตอร์ร่วม ซึ่งทำให้โค้ดยืดหยุ่นมากขึ้นสำหรับการขยายในอนาคต
ข้อได้เปรียบหลักของประเภท sealed คือการจัดการที่ครอบคลุม (exhaustive) ในนิพจน์ when คอมไพเลอร์ตรวจสอบว่าคลาสย่อยที่เป็นไปได้ทั้งหมดถูกครอบคลุม
fun handleResult(result: NetworkResult): String = when (result) {
is NetworkResult.Success -> "Data: ${result.data}"
is NetworkResult.Error -> "Error: ${result.message}"
is NetworkResult.Loading -> "Loading..."
// else ไม่จำเป็น — คอมไพเลอร์รู้ว่าตัวแปรทั้งหมดถูกครอบคลุมแล้ว
}
หากนักพัฒนาเพิ่มคลาสย่อยใหม่ในลำดับชั้น sealed แต่ลืมจัดการใน when — คอมไพเลอร์จะแสดงข้อผิดพลาด นี่คือความปลอดภัยในระดับประเภท ซึ่งไม่มีในลำดับชั้นแบบเปิดที่ใช้สาขา else
ตาม Google Android Developers (2026) คลาส sealed เป็นวิธีที่แนะนำในการจำลองสถานะ UI ใน Jetpack Compose การตรวจสอบ when ที่ครอบคลุมป้องกันสถานะที่นักพัฒนายังไม่ได้จัดการตัวแปรการแสดงผลที่เป็นไปได้ทั้งหมดของหน้าจอ
enum class และ sealed class มักถูกสับสน แต่มีวัตถุประสงค์และความสามารถที่แตกต่างกัน
| คุณลักษณะ | sealed class | enum class |
|---|---|---|
| อินสแตนซ์ | หลายตัว (data class) หนึ่งตัว (object) | หนึ่งตัวต่อค่าคงที่ |
| คุณสมบัติ | แตกต่างกันสำหรับแต่ละคลาสย่อย | เหมือนกันสำหรับทุกค่าคงที่ |
| การสืบทอด | ได้ (จาก sealed class) | ไม่ได้ (final โดยนัย) |
| คอนสตรัคเตอร์ | สามารถมีพารามิเตอร์ | เฉพาะร่วมสำหรับทุกค่าคงที่ |
| ลำดับชั้น | จำกัด, sealed | ชุดค่าคงที่ตายตัว |
การเลือกระหว่าง sealed class และ enum class ขึ้นอยู่กับงาน หากตัวแปรไม่มีข้อมูลเพิ่มเติม — ใช้ enum หากแต่ละตัวแปรมีฟิลด์เฉพาะ — ใช้ sealed class หรือ sealed interface
ประเภท sealed ถูกใช้ในโปรเจกต์ Kotlin สำหรับสถานการณ์มาตรฐานหลายอย่างที่ต้องการการจำลองที่ปลอดภัยของประเภท
แต่ละหน้าจอ Compose สามารถมี sealed class UiState ที่อธิบายสถานะที่เป็นไปได้ทั้งหมด: Idle, Loading, Content(data), Error(exception) นิพจน์ when รับประกันว่าสถานะทั้งหมดถูกจัดการ
NetworkResult ที่มีตัวแปร Success, Error, Loading เป็นรูปแบบมาตรฐานในโปรเจกต์ Kotlin ที่ใช้ Retrofit และ Ktor sealed class รับประกันการจัดการที่ปลอดภัยของแต่ละผลลัพธ์ของคำขอ
sealed interface สำหรับเส้นทางการนำทางช่วยให้โมดูลประกาศเส้นทางของตนเองในขณะที่ยังคงอยู่ในลำดับชั้นที่เป็นหนึ่งเดียว สิ่งนี้กำจัดข้อผิดพลาดเกี่ยวกับเส้นทางที่ไม่รู้จักในเวลาคอมไพล์
ตาม KotlinConf (2025) sealed class และ sealed interface เป็นพื้นฐานของการออกแบบที่ปลอดภัยของประเภทในแอปพลิเคชัน Kotlin สมัยใหม่ พวกมันรวมกับ data class เพื่อจำลองโครงสร้างโดเมนที่ซับซ้อนโดยไม่สูญเสียความปลอดภัยในเวลาคอมไพล์
คำถามที่พบบ่อย
คลาสย่อยโดยตรงทั้งหมดของ sealed class ต้องถูกประกาศในไฟล์เดียวกัน สำหรับ sealed interface ก็ใช้กฎเดียวกัน — การนำไปใช้ในไฟล์เดียว
ไม่ กฎไฟล์เดียวยังใช้กับ sealed interface เช่นกัน การนำไปใช้ทั้งหมดต้องอยู่ในไฟล์ที่ประกาศ sealed interface
sealed interface ไม่มีสถานะหรือคอนสตรัคเตอร์และอนุญาตให้มีการนำไปใช้หลายครั้ง sealed class สามารถมีคอนสตรัคเตอร์และสถานะร่วม แต่คลาสสามารถสืบทอด sealed class ได้เพียงตัวเดียว
คอมไพเลอร์ตรวจสอบความสมบูรณ์ของ when: หากคลาสย่อยทั้งหมดไม่ถูกจัดการ โค้ดจะไม่คอมไพล์ สิ่งนี้กำจัดข้อผิดพลาดขณะรันไทม์และทำให้โค้ดปลอดภัยยิ่งขึ้น
ได้ sealed class สามารถมีคอนสตรัคเตอร์ (private โดยค่าเริ่มต้น) คลาสย่อยทั้งหมดสามารถส่งพารามิเตอร์ไปยังคอนสตรัคเตอร์นี้ผ่าน super()
สรุป
เราจะพัฒนาแอปพลิเคชันบนมือถือแบบครบวงจร
IT Sectr สร้างแอปพลิเคชัน iOS และ Android สำหรับสตาร์ทอัพและธุรกิจตั้งแต่ปี 2017 เราจะให้คำแนะนำและเสนอวิธีแก้ปัญหาที่ดีที่สุดแก่คุณ
อ่านเพิ่มเติม