Sealed Class — คืออะไร หลักการทำงาน และการประยุกต์ใช้

ผู้แต่ง: IT Sectr เผยแพร่เมื่อ: 2026-05-26 เวลาอ่าน: 8 นาที

Sealed Class เป็นคลาสชนิดพิเศษใน Kotlin ที่จำกัดลำดับชั้นการสืบทอดให้อยู่ในชุดย่อยที่。ซับคลาสทั้งหมดถูกประกาศในไฟล์เดียวกันและเป็นที่รู้จักของคอมไพเลอร์ ซึ่งช่วยให้สามารถใช้บล็อก when ที่ครอบคลุมโดยไม่ต้องมีสาขา else ที่บังคับ ตาม Kotlin Docs, 2026 คลาสซีลเป็นกลไกสำคัญสำหรับการแสดงลำดับชั้นที่จำกัด เช่น สถานะ ประเภทข้อผิดพลาด และเหตุการณ์ UI

ประเด็นสำคัญ

  • Sealed Class — คลาสที่มีชุดซับคลาสที่ประกาศในไฟล์เดียวกัน
  • Exhaustive when — คอมไพเลอร์ตรวจสอบว่าซับไทป์ทั้งหมดได้รับการจัดการแล้ว กำจัดสาขา else ที่ถูกลืม
  • Sealed interface — Kotlin 1.5+ รองรับอินเทอร์เฟซซีลสำหรับการสืบทอดหลายรายการ
  • ลำดับชั้นข้อผิดพลาด — sealed class เป็นวิธีมาตรฐานสำหรับการจัดการข้อผิดพลาดแบบ Type-Safe ใน Kotlin
  • ความแตกต่างจาก enum — ซับคลาสแต่ละตัวของ sealed class สามารถมีสถานะเฉพาะและจำนวนฟิลด์ที่แตกต่างกัน

Sealed Class คืออะไร?

Sealed Class (คลาสซีล) คือคลาสใน Kotlin ที่ทำเครื่องหมายด้วยตัวปรับ sealed มันกำหนดลำดับชั้นของประเภทที่จำกัด: ซับคลาสที่เป็นไปได้ทั้งหมดจะถูกระบุในไฟล์เดียวกันและคอมไพเลอร์รู้จักแต่ละตัว สิ่งนี้แยก sealed class ออกจากคลาสเปิดปกติที่ซับคลาสสามารถประกาศได้ทุกที่

วัตถุประสงค์หลักของ sealed class คือ การแสดงชุดตัวเลือกที่จำกัดอย่าง Type-Safe แต่ละซับคลาสสามารถมีโครงสร้างข้อมูลของตัวเอง ทำให้ sealed class ยืดหยุ่นกว่า enum ในรันไทม์ sealed class เป็นคลาสนามธรรมปกติ คอมไพเลอร์กำหนดข้อจำกัดเฉพาะในเวลาคอมไพล์เท่านั้น

Sealed class มีประโยชน์อย่างยิ่งใน สถาปัตยกรรมแอป Android: สถานะ UI ผลลัพธ์คำขอเครือข่าย เหตุการณ์การนำทางคล้าย Intent และแน่นอนลำดับชั้นข้อผิดพลาดเป็นกรณีการใช้งานทั่วไป

ในเวลาคอมไพล์ sealed class จะถูกปรับให้เหมาะสมเป็นตารางกระโดดสำหรับนิพจน์ when ทำให้มีประสิทธิภาพมากกว่า chain if-else เมื่อรวมกับ data class แต่ละซับคลาสสามารถมีไม่เพียงแค่สถานะแต่ยังมีเมธอด ซึ่งช่วยให้สร้างโมเดลโดเมนที่บันทึกตนเองได้โดยไม่ต้องใช้โค้ด Boilerplate

Sealed class ยังมีประสิทธิภาพสำหรับการแสดง สถานะเครื่อง ในแอปพลิเคชันมือถือ แต่ละสถานะเป็นซับคลาสแยกต่างหากพร้อมพารามิเตอร์เฉพาะ และการเปลี่ยนระหว่างสถานะถูกควบคุมผ่านนิพจน์ when คอมไพเลอร์รับประกันว่าสถานะที่เป็นไปได้ทั้งหมดได้รับการจัดการแล้ว กำจัดข้อผิดพลาดรันไทม์เมื่อเปลี่ยนสถานะ UI หรือตรรกะทางธุรกิจ

Sealed Class และ Enum: ความแตกต่างหลัก

นักพัฒนา Kotlin มือใหม่มักสับสนระหว่าง sealed class และ enum เนื่องจากทั้งคู่จำกัดชุดของค่า อย่างไรก็ตาม มีความแตกต่างพื้นฐาน: enum คือชุดของค่าคงที่ประเภทเดียวกัน ในขณะที่ sealed class คือลำดับชั้นของประเภทที่แตกต่างกัน

เมื่อใดควรเลือก enum

Enum เหมาะสมที่สุดเมื่อตัวเลือกทั้งหมดเป็นค่าคงที่โดยไม่มีโครงสร้างเพิ่มเติม ตัวอย่างเช่น วันในสัปดาห์ สถานะคำสั่งซื้อ หรือประเภทการดำเนินการโดยไม่มีพารามิเตอร์ ค่า enum แต่ละค่าคือซิงเกิลตันที่มีชื่อ

เมื่อใดควรเลือก sealed class

Sealed class จำเป็นเมื่อแต่ละตัวเลือกมีข้อมูลของตัวเอง ตัวอย่างเช่น ข้อผิดพลาดเครือข่ายมีรหัสตอบกลับ ข้อผิดพลาดการแจงส่วนมีรายละเอียด และข้อผิดพลาดการอนุญาตมีข้อความ แต่ละซับคลาสของ sealed class คือประเภทแยกต่างหากพร้อมฟิลด์เฉพาะ

kotlin
// Enum — ตัวเลือกทั้งหมดประเภทเดียวกัน
enum class Status { LOADING, SUCCESS, ERROR }

// Sealed class — แต่ละตัวเลือกมีข้อมูลของตัวเอง
sealed class UiState<out T> {
    object Loading : UiState<Nothing>()
    data class Success<T>(val data: T) : UiState<T>()
    data class Error(val message: String) : UiState<Nothing>()
}

Sealed Interface กับ Sealed Class

ตั้งแต่ Kotlin 1.5 เป็นต้นมา สามารถประกาศ sealed interface ได้ สิ่งนี้ขยายแนวคิดซีลไปยังอินเทอร์เฟซ: sealed interface ก็มีชุดการนำไปใช้งานที่เช่นกัน แต่รองรับการสืบทอดหลายรายการ

เมื่อใดควรใช้ sealed interface

Sealed interface สะดวกเมื่อซับคลาสจำเป็นต้องนำสัญญาหลายรายการไปใช้พร้อมกัน ตัวอย่างเช่น เหตุการณ์ UI สามารถคลิกได้และติดตามได้พร้อมกัน ด้วย sealed class คุณต้องเลือกคลาสพื้นฐานหนึ่งคลาส แต่ด้วย sealed interface ซับคลาสนำไปใช้ทั้งสอง

ข้อจำกัดของ sealed class

Sealed class เป็นคลาส ดังนั้นแต่ละซับคลาสสามารถมีพาเรนต์ได้เพียงตัวเดียว Sealed interface แก้ปัญหานี้แต่ไม่สามารถเก็บสถานะได้ การเลือกระหว่างพวกเขาขึ้นอยู่กับงาน: หากต้องการตรรกะที่ใช้ร่วมกันพร้อมฟิลด์ — ใช้ sealed class; หากต้องการความยืดหยุ่นของสัญญา — ใช้ sealed interface

kotlin
sealed interface ScreenEvent {
    data class Refresh(val force: Boolean) : ScreenEvent
    data class Navigate(val route: String) : ScreenEvent
    data class ShowError(val toast: String) : ScreenEvent
}

sealed interface AnalyticsEvent {
    val name: String
    val params: Map<String, Any>
}

// ซับคลาสนำอินเทอร์เฟซทั้งสองไปใช้
data class LoginClicked(
    override val name: String = "login_click",
    override val params: Map<String, Any> = emptyMap()
) : ScreenEvent, AnalyticsEvent

Sealed Class สำหรับลำดับชั้นข้อผิดพลาดในการพัฒนาแอปพลิเคชันมือถือ

หนึ่งในการใช้งานหลักของ sealed class ในการพัฒนาแอปพลิเคชันมือถือคือ ลำดับชั้นข้อผิดพลาดแบบ Type-Safe แทนที่จะโยนข้อยกเว้นประเภทต่าง ๆ หรือใช้ Exception ทั่วไป sealed class รวบรวมข้อผิดพลาดโดเมนที่เป็นไปได้ทั้งหมดไว้ในประเภทเดียว

วิธีสร้างลำดับชั้นข้อผิดพลาด

สร้าง sealed class DomainError และระบุประเภทความล้มเหลวทั้งหมดเป็นซับคลาส แต่ละซับคลาสมีเฉพาะข้อมูลที่เกี่ยวข้องกับประเภทข้อผิดพลาดนั้นโดยเฉพาะ คอมไพเลอร์รับประกันว่าเมื่อจัดการข้อผิดพลาด คุณจะไม่ลืมตัวเลือกใด ๆ

ตัวอย่าง: การจัดการข้อผิดพลาดการตรวจสอบสิทธิ์

พิจารณาแอปพลิเคชันที่มีการอนุญาตซึ่งสถานการณ์ความล้มเหลวต่าง ๆ เป็นไปได้: รหัสผ่านผิด บัญชีถูกบล็อก ปัญหาเซิร์ฟเวอร์ Sealed class รวมพวกเขาเป็นประเภทเดียวด้วยการจัดการที่ครอบคลุม

kotlin
sealed class AuthError {
    data class InvalidCredentials(
        val attempts: Int
    ) : AuthError()

    data class AccountBlocked(
        val until: Long
    ) : AuthError()

    data class NetworkFailure(
        val cause: Throwable
    ) : AuthError()

    object ServerError : AuthError()
}

fun handleError(error: AuthError): String = when (error) {
    is AuthError.InvalidCredentials ->
        "ความพยายามที่เหลือ: ${3 - error.attempts}"
    is AuthError.AccountBlocked ->
        "การเข้าถึงถูกบล็อกจนถึง ${Date(error.until)}"
    is AuthError.NetworkFailure ->
        "ตรวจสอบการเชื่อมต่อ: ${error.cause.localizedMessage}"
    AuthError.ServerError ->
        "เซิร์ฟเวอร์ไม่พร้อมใช้งานชั่วคราว"
}

รูปแบบการใช้งาน Sealed Class ใน Android

Sealed class กลายเป็นเครื่องมือมาตรฐานในสถาปัตยกรรมแอปพลิเคชัน Android มาดูสามรูปแบบหลักที่ sealed class ขาดไม่ได้ในการพัฒนาแอปพลิเคชันมือถือ

  • UI State — การแสดงหน้าจอเป็นสถานะเครื่อง: Loading, Content, Error แต่ละสถานะมีข้อมูลของตัวเอง และ sealed class รับประกันว่าการเปลี่ยนทั้งหมดได้รับการจัดการ
  • Navigation Event — sealed class แทนค่าคงที่การนำทาง: แต่ละหน้าจอเป็นซับคลาสแยกต่างหากพร้อมพารามิเตอร์เส้นทาง คอมไพเลอร์ตรวจสอบประเภทอาร์กิวเมนต์
  • Action/Intent — รูปแบบ Unidirectional Data Flow ใช้ sealed class เพื่อแสดงการดำเนินการทั้งหมดที่ผู้ใช้สามารถทำได้บนหน้าจอ

นอกจากนี้ยังควรสังเกตการใช้ sealed class ใน Clean Architecture แต่ละชั้น (data, domain, presentation) ใช้ sealed class สำหรับประเภทข้อผิดพลาดของตัวเอง และแมปเปอร์แปลง sealed class หนึ่งเป็นอีกอันหนึ่ง ตัวอย่างเช่น DataError จากชั้นข้อมูลถูกแมปเป็น DomainError สำหรับตรรกะทางธุรกิจ จากนั้นเป็น UiState สำหรับชั้นนำเสนอ สิ่งนี้รักษาความปลอดภัยของประเภทในทุกระดับของแอปพลิเคชันและรับประกันว่าไม่มีข้อผิดพลาดใดที่ไม่ได้รับการจัดการ

การทดสอบลำดับชั้น Sealed Class

การทดสอบ sealed class ต้องใช้แนวทางพิเศษ เนื่องจากแต่ละซับคลาสเป็นประเภทแยกต่างหากที่มีสถานะของตัวเอง แนะนำให้เขียนการทดสอบแบบพารามิเตอร์ที่วนซ้ำผ่านซับคลาสทั้งหมดของ sealed class สิ่งนี้รับประกันว่านิพจน์ when ครอบคลุมตัวเลือกทั้งหมด รวมถึงตัวเลือกใหม่ที่เพิ่มเมื่อขยายลำดับชั้น

สำหรับ การทดสอบ UI sealed class ในรูปแบบ UiState ช่วยให้ตรวจสอบการแสดงผลของแต่ละสถานะ: Loading แสดงสปินเนอร์ Content แสดงข้อมูล Error แสดงข้อความข้อผิดพลาด เนื่องจาก sealed class มีจำกัด ความครอบคลุมการทดสอบของทุกรัฐให้ความมั่นใจอย่างสมบูรณ์ในความถูกต้องของตรรกะ UI

ข้อผิดพลาดทั่วไปเมื่อทำงานกับ Sealed Class

แม้ว่าแนวคิดจะเรียบง่าย แต่นักพัฒนามักทำผิดพลาดเมื่อออกแบบลำดับชั้น sealed class มาดูปัญหาหลักและวิธีหลีกเลี่ยง

  • ซับคลาสในไฟล์ต่างกัน — คอมไพเลอร์จะไม่อนุญาตให้ประกาศ sealed class หากซับคลาสอยู่นอกไฟล์ ข้อจำกัดนี้รับประกัน when ที่ครอบคลุม
  • การผสม sealed และ open — sealed class ไม่สามารถเป็น open พร้อมกันได้ หากต้องการลำดับชั้นที่ขยายได้ ให้ใช้ abstract class ปกติ แต่คุณจะเสียความครอบคลุม
  • การซ้อนมากเกินไป — sealed class ใน sealed class สร้างลำดับชั้นที่ลึกซึ่งยากต่อการบำรุงรักษา สำหรับสถานการณ์ง่าย ๆ สองระดับก็เพียงพอ
  • ลืม else ใน when — หาก sealed class จากไลบรารีขาดความครอบคลุม คอมไพเลอร์จะไม่เตือนเกี่ยวกับสาขาที่หายไป เพิ่ม else โดยเจตนาเท่านั้น

คำถามที่พบบ่อย

Sealed class สามารถมีเมธอดนามธรรมได้หรือไม่?

ได้ sealed class สามารถมีเมธอดนามธรรม และแต่ละซับคลาสจำเป็นต้องนำไปใช้ สิ่งนี้สะดวกเมื่อตัวเลือกทั้งหมดต้องให้อินเทอร์เฟสร่วมกันแต่มีตรรกะการดำเนินการที่แตกต่างกัน

Sealed class พร้อมใช้งานใน Java หรือไม่?

ใน Java 17+ มีการแนะนำคลาสและอินเทอร์เฟซซีลด้วยตัวปรับ sealed ปัจจุบัน Android รองรับ Java 17 บางส่วน แต่ในโปรเจกต์ Kotlin sealed class พร้อมใช้งานตั้งแต่ Kotlin 1.0 โดยไม่มีข้อจำกัด

Sealed class สามารถสืบทอดจาก sealed class อื่นได้หรือไม่?

ได้ sealed class หนึ่งสามารถเป็นซับคลาสของอีกอันหนึ่งได้ ลำดับชั้น sealed class ยังคงจำกัด: คอมไพเลอร์รู้จักซับคลาสทั้งหมดในทุกระดับ สิ่งนี้ช่วยให้สร้างการจำแนกข้อผิดพลาดโดยละเอียดได้

Sealed class ส่งผลต่อประสิทธิภาพหรือไม่?

Sealed class ไม่สร้างโอเวอร์เฮดในรันไทม์ คอมไพเลอร์ปรับนิพจน์ when กับ sealed class ให้เหมาะสมเป็นตารางกระโดด (tableswitch) ซึ่งเร็วกว่า chain if-else ประสิทธิภาพเหมือนกับ enum

วิธีทดสอบลำดับชั้น sealed class?

ซับคลาสแต่ละตัวของ sealed class จะถูกทดสอบแยกกัน เนื่องจาก sealed class มีจำกัด คุณสามารถเขียนการทดสอบแบบพารามิเตอร์ที่วนซ้ำผ่านตัวเลือกทั้งหมด สิ่งนี้ให้ความครอบคลุมสมบูรณ์ของสาขาบล็อก when

สรุป

  • Sealed class — คลาสที่มีชุดซับคลาสประกาศในไฟล์เดียว ช่วยให้การวิเคราะห์ when ที่ครอบคลุมในเวลาคอมไพล์
  • แต่ละซับคลาสของ sealed class สามารถมี โครงสร้างข้อมูลของตัวเอง — นี่คือความแตกต่างหลักจาก enum ที่ตัวเลือกทั้งหมดเป็นค่าคงที่ประเภทเดียวกัน
  • Sealed interface (Kotlin 1.5+) รองรับการสืบทอดหลายรายการ sealed class รองรับการสืบทอดเดี่ยวเท่านั้น การเลือกขึ้นอยู่กับความต้องการสถานะที่ใช้ร่วมกัน
  • Sealed class เป็น กลไกมาตรฐาน สำหรับลำดับชั้นข้อผิดพลาดแบบ Type-Safe ใน Kotlin: แต่ละประเภทความล้มเหลวเป็นซับคลาสแยกต่างหากพร้อมฟิลด์ที่เกี่ยวข้อง
  • รูปแบบหลักใน Android: UI State, Navigation Event และ Action/Intent — สร้างบน sealed class เพื่อรับประกันความสมบูรณ์ของการจัดการ
  • หลีกเลี่ยง ซับคลาสในไฟล์ต่างกัน การซ้อนมากเกินไป และการผสม sealed กับ open — สิ่งนี้ละเมิดสัญญาของลำดับชั้นที่จำกัด

เราจะพัฒนาแอปพลิเคชันบนมือถือแบบครบวงจร

IT Sectr สร้างแอปพลิเคชัน iOS และ Android สำหรับสตาร์ทอัพและธุรกิจตั้งแต่ปี 2017 เราจะให้คำแนะนำและเสนอวิธีแก้ปัญหาที่ดีที่สุดแก่คุณ

ปรึกษาโครงการ

อ่านเพิ่มเติม