sealed class và interface trong Kotlin — khái niệm, cú pháp và ứng dụng

Tác giả: IT Sectr Đã đăng: 2026-06-20 Thời gian đọc: 11 phút

sealed class và sealed interface trong Kotlin là các cơ chế phân cấp kiểu giới hạn, nơi tất cả các lớp con có thể có đều được biết tại thời điểm biên dịch. Không giống như các lớp trừu tượng thông thường, sealed class đảm bảo xử lý đầy đủ tất cả các biến thể trong biểu thức when. Theo tài liệu JetBrains Kotlin Language Guide (2026), các kiểu sealed là nền tảng để mô hình hóa trạng thái, màn hình UI và các kiểu kết quả trong các dự án Kotlin.

Những điểm chính

  • sealed — hệ thống phân cấp giới hạn, nơi tất cả lớp con được biết tại thời điểm biên dịch
  • when — xử lý đầy đủ tất cả lớp con mà không cần khối else bắt buộc
  • sealed interface — được thêm vào Kotlin 1.5 cho các hệ thống phân cấp linh hoạt không có hạn chế kế thừa
  • Biên dịch — lỗi biên dịch khi when không đầy đủ cho kiểu sealed
  • Phân cấp — tất cả lớp con phải nằm trong cùng một tệp hoặc bên trong lớp sealed

Sealed class và sealed interface là gì?

sealed class là một lớp trừu tượng với một hạn chế: tất cả các lớp con trực tiếp của nó phải được khai báo trong cùng tệp với chính lớp sealed đó. Hạn chế này làm cho hệ thống phân cấp trở nên kín (sealed) — không có mã nào bên ngoài tệp có thể thêm lớp con mới.

sealed interface, được thêm vào Kotlin 1.5, cung cấp cùng một đảm bảo nhưng với tính linh hoạt của một interface: một sealed interface có thể được triển khai bởi nhiều lớp, đối tượng hoặc các interface khác trong một tệp. Không giống như sealed class, sealed interface không có hạn chế kế thừa đơn — một lớp có thể triển khai nhiều sealed interface cùng lúc.

Theo Kotlin Evolution and Roadmap (2026), sealed interface được thêm vào theo yêu cầu của cộng đồng để mô hình hóa linh hoạt hơn. Động lực chính là khả năng kết hợp các hệ thống phân cấp kiểu độc lập mà không cần kế thừa nhiều lớp.

Cú pháp sealed class

Việc khai báo một sealed class bắt đầu bằng từ khóa sealed trước class. Các lớp con được khai báo trong cùng tệp.

kotlin
sealed class NetworkResult {
    data class Success(val data: String) : NetworkResult()
    data class Error(val message: String) : NetworkResult()
    object Loading : NetworkResult()
}

Mỗi lớp con của một sealed class có thể có các thuộc tính và phương thức riêng. Loading là một singleton (object), Success và Error là các data class với tham số. Trình biên dịch biết cả ba biến thể và kiểm tra tính đầy đủ của chúng khi được sử dụng trong when.

Các sealed class lồng nhau

Các lớp sealed có thể được lồng vào nhau, tạo ra các hệ thống phân cấp đa cấp cho các mô hình dữ liệu phức tạp mà không mất an toàn kiểu.

kotlin
sealed class UiState {
    object Idle : UiState()
    object Loading : UiState()
    data class Content(val items: List<Item>) : UiState()
    data class Error(val exception: Throwable) : UiState()
}

Cú pháp sealed interface (Kotlin 1.5+)

sealed interface được khai báo tương tự như sealed class, nhưng cho phép triển khai nhiều sealed interface trong một lớp.

kotlin
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

Lớp Navigate triển khai hai sealed interface cùng lúc — Action và Loggable. Điều này không thể thực hiện được với sealed class do hạn chế kế thừa đơn. sealed interface cung cấp tính linh hoạt để kết hợp các hệ thống phân cấp độc lập.

Khi nào chọn sealed interface thay vì sealed class

sealed interface được ưu tiên khi hệ thống phân cấp không yêu cầu trạng thái chia sẻ hoặc hàm tạo. Theo JetBrains Kotlin Guidelines (2026), sealed interface nên được sử dụng theo mặc định cho tất cả các hệ thống phân cấp mới nơi không cần hàm tạo chung, giúp mã linh hoạt hơn cho các mở rộng trong tương lai.

Xử lý đầy đủ trong when

Lợi thế chính của các kiểu sealed là xử lý đầy đủ (exhaustive) trong biểu thức when. Trình biên dịch kiểm tra rằng tất cả các lớp con có thể có đều được bao phủ.

kotlin
fun handleResult(result: NetworkResult): String = when (result) {
    is NetworkResult.Success -> "Data: ${result.data}"
    is NetworkResult.Error -> "Error: ${result.message}"
    is NetworkResult.Loading -> "Loading..."
    // else là không bắt buộc — trình biên dịch biết rằng tất cả các biến thể đã được bao phủ
}

Nếu một nhà phát triển thêm một lớp con mới vào hệ thống phân cấp sealed nhưng quên xử lý nó trong when — trình biên dịch sẽ báo lỗi. Đây là sự an toàn ở cấp độ kiểu, không có sẵn với các hệ thống phân cấp mở sử dụng nhánh else.

Theo Google Android Developers (2026), các lớp sealed là cách được khuyến nghị để mô hình hóa trạng thái UI trong Jetpack Compose. Kiểm tra đầy đủ của when ngăn chặn các trạng thái nơi nhà phát triển chưa xử lý tất cả các biến thể hiển thị có thể có của một màn hình.

So sánh sealed class với enum class

enum class và sealed class thường bị nhầm lẫn, nhưng chúng có mục đích và khả năng khác nhau.

Đặc điểmsealed classenum class
Thể hiệnNhiều (data class), một (object)Chính xác một mỗi hằng số
Thuộc tínhKhác nhau cho mỗi lớp conGiống nhau cho tất cả hằng số
Kế thừaCó (từ sealed class)Không (ngầm final)
Hàm tạoCó thể có tham sốChỉ chia sẻ cho tất cả hằng số
Phân cấpGiới hạn, sealedTập hằng số cố định

Việc lựa chọn giữa sealed class và enum class phụ thuộc vào nhiệm vụ. Nếu các biến thể không mang dữ liệu bổ sung — hãy sử dụng enum. Nếu mỗi biến thể chứa các trường duy nhất — hãy sử dụng sealed class hoặc sealed interface.

Các kịch bản sử dụng thực tế

Các kiểu sealed được sử dụng trong các dự án Kotlin cho một loạt các kịch bản tiêu chuẩn nơi cần mô hình hóa an toàn kiểu.

Trạng thái UI trong Jetpack Compose

Mỗi màn hình Compose có thể có một sealed class UiState mô tả tất cả các trạng thái có thể: Idle, Loading, Content(data), Error(exception). Biểu thức when đảm bảo rằng tất cả các trạng thái đều được xử lý.

Kết quả yêu cầu mạng

NetworkResult với các biến thể Success, Error, Loading là một mẫu tiêu chuẩn trong các dự án Kotlin sử dụng Retrofit và Ktor. sealed class đảm bảo xử lý an toàn mỗi kết quả yêu cầu.

Điều hướng trong các dự án đa mô-đun

sealed interface cho các tuyến điều hướng cho phép các mô-đun khai báo tuyến riêng của chúng trong khi vẫn nằm trong một hệ thống phân cấp thống nhất. Điều này loại bỏ các lỗi với các tuyến không xác định tại thời điểm biên dịch.

Theo KotlinConf (2025), sealed class và sealed interface là nền tảng của thiết kế an toàn kiểu trong các ứng dụng Kotlin hiện đại. Chúng kết hợp với data class để mô hình hóa các cấu trúc miền phức tạp mà không mất an toàn tại thời điểm biên dịch.

Câu hỏi thường gặp

Các lớp con của sealed class nên được khai báo ở đâu?

Tất cả các lớp con trực tiếp của một sealed class phải được khai báo trong cùng tệp. Đối với sealed interface cũng áp dụng quy tắc tương tự — triển khai trong một tệp.

Sealed interface có thể có triển khai trong một tệp khác không?

Không, quy tắc một tệp cũng áp dụng cho sealed interface. Tất cả các triển khai phải nằm trong tệp nơi sealed interface được khai báo.

Sự khác biệt giữa sealed class và sealed interface là gì?

sealed interface không có trạng thái hoặc hàm tạo và cho phép triển khai nhiều lần. sealed class có thể có hàm tạo và trạng thái chia sẻ, nhưng một lớp chỉ có thể kế thừa một sealed class.

Các lớp sealed giúp ích gì trong biểu thức when?

Trình biên dịch kiểm tra tính đầy đủ của when: nếu không phải tất cả các lớp con đều được xử lý, mã sẽ không biên dịch. Điều này loại bỏ lỗi thời gian chạy và làm cho mã an toàn hơn.

Sealed class có thể có hàm tạo không?

Có, một sealed class có thể có hàm tạo (mặc định là private). Tất cả các lớp con có thể truyền tham số cho hàm tạo này thông qua super().

Tóm tắt

  • sealed class — hệ thống phân cấp giới hạn với các lớp con được biết tại thời điểm biên dịch
  • sealed interface — giải pháp thay thế linh hoạt (Kotlin 1.5+) hỗ trợ triển khai nhiều lần
  • when — xử lý đầy đủ với kiểm tra của trình biên dịch, không cần else
  • Một tệp — tất cả các lớp con và triển khai phải nằm trong cùng tệp với kiểu sealed
  • Mô hình hóa — trạng thái UI, kết quả mạng, điều hướng, hệ thống sự kiện
  • An toàn — thêm lớp con mới mà không xử lý trong when gây ra lỗi biên dịch
  • Lựa chọn — sealed interface được ưu tiên theo mặc định, sealed class khi cần trạng thái chia sẻ

Chúng tôi sẽ phát triển ứng dụng di động chìa khóa trao tay

IT Sectr tạo các ứng dụng iOS và Android cho các công ty khởi nghiệp và doanh nghiệp từ năm 2017. Chúng tôi sẽ tư vấn và đề xuất giải pháp tốt nhất cho bạn.

Thảo luận dự án

Đọc thêm