Что такое sealed классы в Kotlin?
sealed классы в Kotlin (от англ. sealed — запечатанный) — это ограниченные иерархии классов, где все возможные подклассы известны на момент компиляции. Они предназначены для моделирования ограниченных наборов состояний и часто используются в when-выражениях без необходимости писать else.
sealed — альтернатива enum, но более мощная: каждый подкласс может иметь своё состояние и поведение.
🔐 Основная идея
Когда ты объявляешь класс как sealed, ты ограничиваешь список его наследников — они должны быть определены в том же файле, что и sealed-класс.
sealed class Result
data class Success(val data: String) : Result()
data class Error(val exception: Throwable) : Result()
object Loading : Result()
📌 Особенности sealed class
-
Абстрактные по сути (нельзя создать экземпляр базового sealed-класса).
-
Подклассы могут быть data, object, обычными классами.
-
Все наследники должны быть в том же файле.
-
Отлично работают с when — компилятор проверяет полноту (exhaustiveness) веток.
🧠 Пример использования
fun handle(result: Result): String = when (result) {
is Success -> "Данные: ${result.data}"
is Error -> "Ошибка: ${result.exception.message}"
Loading -> "Загрузка..."
// else не нужен — все варианты известны
}
Компилятор проверяет, что ты обработал все случаи — и если забыл какой-то подкласс, будет ошибка.
🔄 Сравнение с другими структурами
Тип | Поддержка состояния | Расширяемость | Использование в when без else |
---|---|---|---|
enum | Нет (только поля) | Нет | Да |
--- | --- | --- | --- |
sealed class | Да (val, fun) | Нет (в одном файле) | Да |
--- | --- | --- | --- |
open class | Да | Да | Нет |
--- | --- | --- | --- |
📦 Пример реального применения
Состояния UI:
sealed class UiState
object Idle : UiState()
object Loading : UiState()
data class Success(val content: String) : UiState()
data class Error(val message: String) : UiState()
Обработка результата:
fun update(state: UiState) = when (state) {
is Idle -> showIdle()
is Loading -> showLoading()
is Success -> showContent(state.content)
is Error -> showError(state.message)
}
✏️ Сравнение с sealed interface
С Kotlin 1.5+ появился sealed interface — аналог sealed class, но не требует быть классом:
sealed interface NetworkState
object Connected : NetworkState
object Disconnected : NetworkState
✅ Когда использовать sealed class
-
Для представления замкнутых множеств состояний.
-
Вместо enum, когда у вариантов должны быть разные данные.
-
Когда хочется type-safe обработку через when.
-
В паттерне Result/State/Error, Event, UI State, Intent в MVI/Redux.
Таким образом, sealed class — мощный инструмент для безопасного моделирования конечных состояний и исчерпывающей обработки в when. Они делают код безопаснее, выразительнее и избавляют от лишнего else.