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 няма ограничение за единично наследяване — един клас може да имплементира няколко sealed интерфейса едновременно.
Според 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, но позволява имплементация на множество sealed интерфейси в един клас.
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 имплементира едновременно два sealed интерфейса — 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) | Не (implicit 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 са основата на type-safe дизайна в съвременните 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 г. Ще ви консултираме и ще предложим най-доброто решение.
Прочетете също