Что такое sealed class?
sealed class в Kotlin — это запечатанный (sealed) абстрактный класс, который позволяет ограничить множество его подклассов, делая его отличным инструментом для безопасной работы с иерархией типов, особенно в when-выражениях.
Такие классы часто применяются при работе с состояниями UI, результатами запросов, ошибками, событиями и навигацией. Они упрощают контроль над логикой, когда объект может быть только одним из нескольких известных вариантов.
📦 Пример
sealed class Result
data class Success(val data: String) : Result()
data class Error(val exception: Throwable) : Result()
object Loading : Result()
🔍 Особенности sealed-классов
1. Ограниченное множество наследников
Все подклассы sealed class должны находиться в одном файле. Это позволяет компилятору знать обо всех возможных вариантах, и делает when-выражения исчерпывающими без else.
fun handle(result: Result) = when (result) {
is Success -> println("Data: ${result.data}")
is Error -> println("Error: ${result.exception.message}")
is Loading -> println("Loading...")
// else не нужен: компилятор знает все варианты
}
2. Абстрактность по умолчанию
sealed class по умолчанию — абстрактный. Нельзя создать её напрямую:
val r = Result() // ❌ ошибка
Можно использовать только её подклассы.
3. Поддержка object, data class, обычных классов
Внутри sealed class можно использовать:
-
object — для уникальных состояний (Loading, Idle);
-
data class — для хранения данных (Success, Error);
-
обычные классы — если нужны более сложные реализации.
4. Может быть вложенным или внешним классом
Sealed-классы можно объявлять как:
sealed class Event {
object Click : Event()
data class Input(val text: String) : Event()
}
или как отдельный класс с наследниками в том же файле:
sealed class Operation
class Add(val a: Int, val b: Int) : Operation()
class Multiply(val a: Int, val b: Int) : Operation()
🧠 Когда использовать sealed class
-
UI-состояния: Loading, Success, Error, Empty.
-
Результаты операций: Success<T>, Failure, InProgress.
-
Навигационные события: NavigateToLogin, ShowToast.
-
Обработка ошибок: HttpError, Timeout, NoInternet.
✅ Преимущества
Преимущество | Описание |
---|---|
✅ Безопасность | Компилятор знает все возможные подклассы. |
--- | --- |
✅ Упрощение when-блоков | Не нужен else, если охвачены все варианты. |
--- | --- |
✅ Лаконичный код | Позволяет компактно описывать состояния. |
--- | --- |
✅ Статическая проверка на полноту | Помогает не забыть обработать случай. |
--- | --- |
⚠️ Ограничения
-
Все наследники должны быть в одном файле.
-
Не поддерживает многослойную иерархию, как abstract class.
-
Не подходит, если нужно позволить расширение класса в другом модуле.
🔁 Сравнение с другими
Тип | Можно расширять в других файлах? | Компилятор знает всех наследников? |
---|---|---|
sealed | ❌ Нет | ✅ Да |
--- | --- | --- |
abstract | ✅ Да | ❌ Нет |
--- | --- | --- |
enum | ❌ Нет | ✅ Да (но только фиксированные object) |
--- | --- | --- |
Итого
sealed class — мощный инструмент в Kotlin для ограниченной и контролируемой иерархии типов. Он делает код безопасным, понятным и удобным для расширения, особенно при моделировании состояний, событий или результатов, которые могут иметь ограниченное число вариантов.