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 не имеет ограничения на single inheritance — класс может реализовать несколько 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 — это singleton (object), Success и Error — data class с параметрами. Компилятор знает все три варианта и проверяет их полноту при использовании in when.
sealed классы могут быть вложенными, создавая многоуровневые иерархии для сложных моделей данных без потери type safety.
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 такое невозможно из-за ограничения single inheritance. 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 is not required — compiler knows all variants are covered
}
Если разработчик добавит новый подкласс в 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-проектах для ряда стандартных сценариев, где требуется type-safe моделирование.
Каждый экран 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: если обработаны не все подклассы, код не компилируется. Это исключает ошибки runtime и делает код безопаснее.
Да, sealed class может иметь конструктор (по умолчанию private). Все подклассы могут передавать параметры в этот конструктор через super()
Итоги
Мы разработаем мобильное приложение под ключ
IT Sectr создаёт приложения для iOS и Android для стартапов и бизнеса с 2017 года. Мы проконсультируем вас и предложим наилучшее решение.
Читайте также