Sealed Class, Kotlin'de kalıtım hiyerarşisini sabit bir alt tür kümesiyle sınırlayan özel bir sınıf türüdür. Tüm alt sınıflar aynı dosyada bildirilir ve derleyici tarafından bilinir, bu da zorunlu else dalı olmadan kapsamlı bir when bloğu kullanılmasına olanak tanır. Kotlin Docs, 2026'ya göre, mühürlü sınıflar durumlar, hata türleri ve UI olayları gibi sınırlı hiyerarşileri temsil etmek için önemli bir mekanizmadır.
Önemli Noktalar
Sealed Class (mühürlü sınıf), Kotlin'de sealed değiştiricisiyle işaretlenmiş bir sınıftır. Sınırlı bir tür hiyerarşisi tanımlar: olası tüm alt sınıflar aynı dosyada listelenir ve derleyici her birini bilir. Bu, sealed class'ı alt sınıfları her yerde bildirilebilen sıradan bir açık sınıftan ayırır.
Sealed class'ın temel amacı, sonlu bir varyant kümesinin tür güvenli temsilidir. Her alt sınıfın kendi veri yapısı olabilir, bu da sealed class'ı enum'dan daha esnek hale getirir. Çalışma zamanında, sealed class sıradan bir soyut sınıftır; derleyici yalnızca derleme zamanında kısıtlamalar uygular.
Sealed class özellikle Android uygulama mimarisinde faydalıdır: UI durumları, ağ isteği sonuçları, Intent benzeri gezinme olayları ve tabii ki hata hiyerarşileri tipik kullanım durumlarıdır.
Derleme zamanında, sealed class when ifadeleri için bir atlama tablosuna optimize edilir ve bu onu if-else zincirlerinden daha verimli hale getirir. data class ile birleştirildiğinde, her alt sınıf yalnızca durumu değil aynı zamanda yöntemleri de içerebilir, bu da standart kod olmadan kendi kendini belgeleyen alan modelleri oluşturulmasına olanak tanır.
Sealed class, mobil uygulamalarda durum makinelerini temsil etmek için de etkilidir. Her durum, benzersiz parametrelere sahip ayrı bir alt sınıftır ve durumlar arasındaki geçişler when ifadeleri aracılığıyla kontrol edilir. Derleyici, tüm olası durumların işlendiğini garanti eder ve UI durumu veya iş mantığı değiştirilirken çalışma zamanı hatalarını ortadan kaldırır.
Yeni başlayan Kotlin geliştiricileri genellikle sealed class ile enum'u karıştırır, çünkü her ikisi de değer kümesini sınırlar. Ancak, temel bir fark vardır: enum aynı türdeki sabitlerin bir kümesidir, sealed class ise farklı türlerin bir hiyerarşisidir.
Enum, tüm varyantlar ek yapı olmadan sabit olduğunda idealdir. Örneğin, haftanın günleri, sipariş durumları veya parametresiz eylem türleri. Her enum değeri, sabit bir ada sahip bir teklidir.
Sealed class, her varyantın kendi verisine sahip olduğunda gereklidir. Örneğin, bir ağ hatası yanıt kodu içerir, bir ayrıştırma hatası ayrıntılar içerir ve bir yetkilendirme hatası bir mesaj içerir. sealed class'ın her alt türü, benzersiz alanlara sahip ayrı bir türdür.
// Enum — aynı türdeki tüm varyantlar
enum class Status { LOADING, SUCCESS, ERROR }
// Sealed class — her varyant kendi verileriyle
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>()
}
Kotlin 1.5'ten itibaren sealed interface bildirmek mümkündür. Bu, mühürleme kavramını arayüzlere genişletir: sealed interface de sabit bir uygulama kümesine sahiptir ancak çoklu kalıtımı destekler.
Sealed interface, alt türlerin aynı anda birden çok sözleşmeyi uygulaması gerektiğinde kullanışlıdır. Örneğin, bir UI olayı hem tıklanabilir hem de izlenebilir olabilir. sealed class ile bir temel sınıf seçmeniz gerekir; sealed interface ile alt tür her ikisini de uygular.
Sealed class bir sınıftır, bu nedenle her alt türün yalnızca bir ebeveyni olabilir. Sealed interface bu sorunu çözer ancak durum içeremez. Aralarındaki seçim göreve bağlıdır: alanlarla paylaşılan mantık gerekiyorsa — sealed class kullanın; sözleşme esnekliği gerekiyorsa — sealed interface kullanın.
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>
}
// Alt tür her iki arayüzü de uygular
data class LoginClicked(
override val name: String = "login_click",
override val params: Map<String, Any> = emptyMap()
) : ScreenEvent, AnalyticsEvent
Mobil geliştirmede sealed class'ın ana kullanımlarından biri tür güvenli hata hiyerarşileridir. Farklı türlerde istisnalar fırlatmak veya genel bir Exception kullanmak yerine, sealed class olası tüm alan hatalarını tek bir türde toplar.
DomainError adlı bir sealed class oluşturun ve tüm başarısızlık türlerini alt tür olarak listeleyin. Her alt tür, yalnızca o belirli hata türüyle ilgili verileri içerir. Derleyici, hatayı işlerken herhangi bir varyantı unutmayacağınızı garanti eder.
Farklı başarısızlık senaryolarının mümkün olduğu bir yetkilendirme uygulaması düşünün: yanlış şifre, hesap bloke, sunucu sorunu. Sealed class bunları kapsamlı işleme ile tek bir türde birleştirir.
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 ->
"Kalan deneme: ${3 - error.attempts}"
is AuthError.AccountBlocked ->
"${Date(error.until)} tarihine kadar erişim engellendi"
is AuthError.NetworkFailure ->
"Bağlantıyı kontrol edin: ${error.cause.localizedMessage}"
AuthError.ServerError ->
"Sunucu geçici olarak kullanılamıyor"
}
Sealed class, Android uygulama mimarisinde standart bir araç haline gelmiştir. Mobil geliştirmede sealed class'ın vazgeçilmez olduğu üç ana şablona bakalım.
Clean Architecture'da sealed class kullanımı da dikkat çekicidir. Her katman (data, domain, presentation) kendi hata türleri için sealed class kullanır ve dönüştürücüler bir sealed class'ı diğerine dönüştürür. Örneğin, veri katmanından DataError, iş mantığı için DomainError'a ve ardından sunum katmanı için UiState'e dönüştürülür. Bu, uygulamanın tüm seviyelerinde tür güvenliğini korur ve hiçbir hatanın işlenmemiş kalmamasını garanti eder.
Test etme, her alt tür kendi durumuna sahip ayrı bir tür olduğu için sealed class özel bir yaklaşım gerektirir. sealed class'ın tüm alt türlerini dolaşan parametreli testler yazmanız önerilir. Bu, when ifadelerinin, hiyerarşi genişletilirken eklenen yenileri de dahil olmak üzere tüm varyantları kapsamasını garanti eder.
UI testleri için sealed class'ı UiState olarak kullanmak, her durumun görüntülenmesini kontrol etmeyi sağlar: Loading bir döndürücü gösterir, Content veri gösterir, Error bir hata mesajı gösterir. sealed class sonlu olduğu için, tüm durumların test kapsamı UI mantığının doğruluğuna tam güven verir.
Kavramın basitliğine rağmen, geliştiriciler sealed class hiyerarşileri tasarlarken düzenli olarak hatalar yapar. Ana sorunlara ve bunlardan nasıl kaçınılacağına bakalım.
Sıkça Sorulan Sorular
Evet, bir sealed class soyut yöntemler içerebilir ve her alt tür bunları uygulamak zorundadır. Bu, tüm varyantların ortak bir arayüz sağlaması gerektiğinde ancak farklı yürütme mantığına sahip olduğunda kullanışlıdır.
Java 17+'de, sealed değiştiricisiyle mühürlü sınıflar ve arayüzler tanıtılmıştır. Android şu anda Java 17'yi kısmen desteklemektedir, ancak Kotlin projelerinde sealed class Kotlin 1.0'dan itibaren herhangi bir kısıtlama olmaksızın mevcuttur.
Evet, bir sealed class başka bir sealed class'ın alt türü olabilir. sealed class hiyerarşisi sonlu kalır: derleyici her seviyedeki tüm alt türleri bilir. Bu, ayrıntılı hata sınıflandırmaları oluşturulmasına olanak tanır.
Sealed class çalışma zamanında ek yük oluşturmaz. Derleyici, sealed class ile when ifadelerini atlama tablolarına (tableswitch) optimize eder, bu da if-else zincirlerinden daha hızlıdır. Performans enum ile aynıdır.
Sealed class'ın her alt türü ayrı ayrı test edilir. sealed class sonlu olduğu için, tüm varyantları dolaşan parametreli bir test yazabilirsiniz. Bu, when bloğunun dallarının tam kapsamını sağlar.
Özet
Anahtar teslim bir mobil uygulama geliştireceğiz
IT Sectr, 2017'den beri girişimler ve işletmeler için iOS ve Android uygulamaları oluşturmaktadır. Size danışmanlık yapacak ve en iyi çözümü önereceğiz.
Ayrıca okuyun