Что такое 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.