Sealed Class — apa itu, prinsip kerja dan penerapan

Penulis: IT Sectr Diterbitkan: 2026-05-26 Waktu membaca: 8 mnt

Sealed Class — tipe kelas khusus dalam Kotlin yang membatasi hierarki pewarisan ke serangkaian subtipe tetap. Semua pewaris dideklarasikan dalam file yang sama dan diketahui oleh kompiler, yang memungkinkan penggunaan blok when yang lengkap tanpa cabang else wajib. Menurut Kotlin Docs, 2026, kelas tersegel adalah mekanisme kunci untuk merepresentasikan hierarki terbatas seperti status, jenis kesalahan, dan peristiwa UI.

Poin Utama

  • Sealed Class — kelas dengan serangkaian pewaris tetap yang dideklarasikan dalam file yang sama.
  • Exhaustive when — kompiler memeriksa bahwa semua subtipe telah diproses, menghilangkan cabang else yang terlupakan.
  • Sealed interface — Kotlin 1.5+ mendukung antarmuka tersegel untuk pewarisan berganda.
  • Hierarki kesalahan — sealed class adalah cara standar penanganan kesalahan yang aman tipe di Kotlin.
  • Perbedaan dari enum — setiap pewaris sealed class dapat berisi status unik dan jumlah bidang yang berbeda.

Apa itu Sealed Class?

Sealed Class (kelas tersegel) — adalah kelas dalam Kotlin yang ditandai dengan pengubah sealed. Ia mendefinisikan hierarki tipe terbatas: semua pewaris yang mungkin dicantumkan dalam file yang sama, dan kompiler mengetahui masing-masingnya. Ini membedakan sealed class dari kelas terbuka biasa, yang pewarisnya dapat dideklarasikan di mana saja.

Tujuan utama sealed class adalah representasi yang aman tipe dari serangkaian varian terbatas. Setiap pewaris dapat memiliki struktur data sendiri, yang membuat sealed class lebih fleksibel daripada enum. Saat runtime, sealed class adalah kelas abstrak biasa, kompiler menerapkan batasan hanya pada tahap kompilasi.

Sealed class sangat berguna dalam arsitektur Android aplikasi: status UI, hasil permintaan jaringan, peristiwa navigasi mirip Intent, dan tentu saja hierarki kesalahan — skenario penerapan yang umum.

Saat kompilasi, sealed class dioptimalkan menjadi tabel transisi untuk ekspresi when, menjadikannya lebih efisien daripada rantai if-else. Dalam kombinasi dengan data class, setiap pewaris dapat berisi tidak hanya status, tetapi juga metode, memungkinkan pembangunan model domain yang mendokumentasikan diri sendiri tanpa kode boilerplate.

Sealed class juga efektif untuk merepresentasikan mesin keadaan terbatas (state machine) dalam aplikasi mobile. Setiap status — pewaris terpisah dengan parameter unik, dan transisi antar status dikendalikan melalui ekspresi when. Kompiler menjamin bahwa semua kemungkinan status telah diproses, yang menghilangkan kesalahan runtime saat perubahan status UI atau logika bisnis.

Sealed Class dan Enum: perbedaan utama

Pengembang Kotlin pemula sering bingung membedakan sealed class dengan enum, karena keduanya membatasi kumpulan nilai. Namun ada perbedaan mendasar di antara keduanya: enum — adalah kumpulan konstanta dari satu tipe, sealed class — hierarki tipe yang berbeda.

Kapan memilih enum

Enum optimal ketika semua varian adalah konstanta tanpa struktur tambahan. Misalnya hari dalam seminggu, status pesanan, atau jenis tindakan tanpa parameter. Setiap nilai enum adalah singleton dengan nama tetap.

Kapan memilih sealed class

Sealed class diperlukan ketika setiap varian memiliki data sendiri. Misalnya, kesalahan jaringan berisi kode respons, kesalahan parsing — detail, dan kesalahan otorisasi — pesan. Setiap pewaris sealed class adalah tipe terpisah dengan bidang unik.

kotlin
// Enum — semua varian dari satu tipe
enum class Status { LOADING, SUCCESS, ERROR }

// Sealed class — setiap varian dengan datanya sendiri
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 versus Sealed Class

Sejak Kotlin 1.5, ada kemungkinan untuk mendeklarasikan sealed interface. Ini memperluas konsep sealed ke antarmuka: sealed interface juga memiliki kumpulan implementasi tetap, tetapi mendukung pewarisan berganda.

Kapan menggunakan sealed interface

Sealed interface nyaman ketika pewaris harus mengimplementasikan beberapa kontrak secara bersamaan. Misalnya, peristiwa UI dapat sekaligus dapat diklik dan dapat dilacak. Dengan sealed class, seseorang harus memilih satu kelas dasar, dengan sealed interface pewaris mengimplementasikan keduanya.

Keterbatasan sealed class

Sealed class adalah kelas, jadi setiap pewaris hanya dapat memiliki satu induk. Sealed interface memecahkan masalah ini, tetapi tidak dapat berisi status. Pilihan di antara keduanya tergantung pada tugas: diperlukan logika umum dengan bidang — sealed class, diperlukan fleksibilitas kontrak — 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>
}

// Pewaris mengimplementasikan kedua antarmuka
data class LoginClicked(
    override val name: String = "login_click",
    override val params: Map<String, Any> = emptyMap()
) : ScreenEvent, AnalyticsEvent

Sealed Class untuk hierarki kesalahan dalam pengembangan mobile

Salah satu penerapan utama sealed class dalam pengembangan mobile — hierarki kesalahan yang aman tipe. Alih-alih melempar pengecualian dari berbagai jenis atau menggunakan Exception umum, sealed class mengumpulkan semua kemungkinan kesalahan domain dalam satu tipe.

Cara membangun hierarki kesalahan

Buat sealed class DomainError dan cantumkan semua jenis kegagalan sebagai pewaris. Setiap pewaris hanya berisi data yang berarti untuk jenis kesalahan tersebut. Kompiler menjamin bahwa saat menangani kesalahan, Anda tidak akan melupakan varian apa pun.

Contoh: penanganan kesalahan autentikasi

Pertimbangkan aplikasi dengan otorisasi, di mana berbagai skenario kegagalan mungkin terjadi: kata sandi salah, pemblokiran akun, masalah server. Sealed class menyatukannya dalam satu tipe dengan penanganan yang lengkap.

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 ->
        "Sisa percobaan: ${3 - error.attempts}"
    is AuthError.AccountBlocked ->
        "Akses diblokir hingga ${Date(error.until)}"
    is AuthError.NetworkFailure ->
        "Periksa koneksi: ${error.cause.localizedMessage}"
    AuthError.ServerError ->
        "Server untuk sementara tidak tersedia"
}

Pola penggunaan Sealed Class di Android

Sealed class telah menjadi alat standar dalam arsitektur aplikasi Android. Mari kita lihat tiga pola utama di mana sealed class sangat diperlukan dalam pengembangan mobile.

  • UI State — representasi layar sebagai mesin keadaan terbatas: Loading, Content, Error. Setiap status berisi datanya sendiri, dan sealed class menjamin bahwa semua transisi telah diproses.
  • Navigation Event — sealed class alih-alih konstanta navigasi: setiap layar adalah pewaris terpisah dengan parameter rute. Kompiler memeriksa tipe argumen.
  • Action/Intent — pola Unidirectional Data Flow menggunakan sealed class untuk merepresentasikan semua tindakan yang dapat dilakukan pengguna di layar.

Secara terpisah, perlu disebutkan penerapan sealed class dalam Clean Architecture. Setiap lapisan (data, domain, presentation) menggunakan sealed class untuk jenis kesalahannya sendiri, dan mapper mengubah satu sealed class ke yang lain. Misalnya, DataError dari lapisan data dipetakan ke DomainError untuk logika bisnis, kemudian ke UiState untuk lapisan presentasi. Ini menjaga keamanan tipe di semua level aplikasi dan menjamin bahwa tidak ada kesalahan yang tidak tertangani.

Pengujian hierarki sealed class

Pengujian sealed class memerlukan pendekatan khusus, karena setiap pewaris adalah tipe terpisah dengan statusnya sendiri. Disarankan untuk menulis tes parameter yang melewati semua pewaris sealed class. Ini menjamin bahwa ekspresi when mencakup semua varian, termasuk yang baru ditambahkan saat memperluas hierarki.

Untuk tes UI, sealed class sebagai UiState memungkinkan pemeriksaan tampilan setiap status: Loading menampilkan spinner, Content — data, Error — pesan kesalahan. Karena sealed class terbatas, cakupan tes semua status memberikan keyakinan penuh atas kebenaran logika UI.

Kesalahan umum saat bekerja dengan Sealed Class

Meskipun konsepnya sederhana, pengembang sering membuat kesalahan saat merancang hierarki sealed class. Mari kita lihat masalah utama dan cara menghindarinya.

  • Pewaris di file berbeda — kompiler tidak akan mengizinkan deklarasi sealed class jika pewaris berada di luar file. Batasan ini menjamin when yang lengkap.
  • Mencampur sealed dan open — sealed class tidak bisa menjadi open secara bersamaan. Jika diperlukan hierarki yang dapat diperluas, gunakan abstract class biasa, tetapi Anda akan mengorbankan kelengkapan.
  • Bersarang berlebihan — sealed class di dalam sealed class menciptakan hierarki dalam yang sulit dipelihara. Untuk skenario sederhana, dua tingkat sudah cukup.
  • Else terlupakan di when — jika sealed class dari perpustakaan tidak memiliki kelengkapan, kompiler tidak akan memperingatkan tentang cabang yang terlewat. Tambahkan else hanya secara sadar.

Pertanyaan yang Sering Diajukan

Bisakah sealed class memiliki metode abstrak?

Ya, sealed class dapat berisi metode abstrak, dan setiap pewaris wajib mengimplementasikannya. Ini nyaman ketika semua varian harus menyediakan antarmuka umum, tetapi dengan logika eksekusi yang berbeda.

Apakah sealed class tersedia di Java?

Di Java 17+ telah muncul kelas dan antarmuka tersegel dengan pengubah sealed. Android saat ini mendukung Java 17 sebagian, tetapi di proyek Kotlin, sealed class tersedia sejak Kotlin 1.0 tanpa batasan.

Bisakah sealed class mewarisi dari sealed class lain?

Ya, satu sealed class dapat menjadi pewaris yang lain. Hierarki sealed class tetap terbatas: kompiler mengetahui semua pewaris di setiap level. Ini memungkinkan pembangunan klasifikasi kesalahan yang terperinci.

Apakah sealed class mempengaruhi kinerja?

Sealed class tidak menimbulkan overhead saat runtime. Kompiler mengoptimalkan ekspresi when dengan sealed class menjadi tabel transisi (tableswitch), yang lebih cepat daripada rantai if-else. Kinerjanya identik dengan enum.

Bagaimana cara menguji hierarki sealed class?

Setiap pewaris sealed class diuji secara terpisah. Karena sealed class terbatas, tes parameter dapat ditulis yang melewati semua varian. Ini memberikan cakupan lengkap cabang blok when.

Kesimpulan

  • Sealed class — kelas dengan serangkaian pewaris tetap yang dideklarasikan dalam satu file, memberikan analisis when yang lengkap pada tahap kompilasi.
  • Setiap pewaris sealed class dapat memiliki struktur data sendiri — perbedaan utama dari enum, di mana semua varian adalah konstanta dari satu tipe.
  • Sealed interface (Kotlin 1.5+) mendukung pewarisan berganda, sealed class — hanya pewarisan tunggal. Pilihan tergantung pada kebutuhan akan status bersama.
  • Sealed class — mekanisme standar untuk hierarki kesalahan yang aman tipe di Kotlin: setiap jenis kegagalan adalah pewaris terpisah dengan bidang yang relevan.
  • Pola utama di Android: UI State, Navigation Event, dan Action/Intent — dibangun di atas sealed class untuk menjamin kelengkapan pemrosesan.
  • Hindari pewaris di file berbeda, bersarang berlebihan, dan mencampur sealed dengan open — ini melanggar kontrak hierarki terbatas.

Kami akan mengembangkan aplikasi seluler turnkey

IT Sectr membuat aplikasi iOS dan Android untuk startup dan bisnis sejak 2017. Kami akan memberi saran dan mengusulkan solusi terbaik.

Diskusikan proyek

Baca juga