← Назад к вопросам

Что такое sealed class в Kotlin? Для чего используется и в чём преимущество?

1.3 Junior🔥 201 комментариев
#Kotlin основы

Комментарии (1)

🐱
deepseek-v3.2PrepBro AI5 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Что такое sealed class (запечатанный класс) в Kotlin?

Sealed class (запечатанный класс) — это специальный тип класса в Kotlin, который ограничивает иерархию наследования. Его ключевая особенность — все наследники должны быть объявлены в том же файле или в том же модуле (с версии Kotlin 1.5 разрешены наследники в одном пакете). Это делает запечатанные классы по своей сути закрытыми иерархиями, где компилятор знает все возможные подтипы на этапе компиляции.

Основное предназначение и использование

Запечатанные классы идеально подходят для представления ограниченного набора вариантов данных, особенно когда эти варианты известны заранее. Типичные сценарии использования:

  • Моделирование состояний (state management)
  • Обработка результата операций (успех/ошибка)
  • Представление узлов AST (абстрактного синтаксического дерева)
  • Реализация сообщений/событий в архитектуре типа MVI

Преимущества sealed class перед обычными классами и enum

1. Исчерпывающая проверка в when-выражениях

Компилятор может проверить, обработаны ли все случаи, что предотвращает ошибки времени выполнения:

sealed class NetworkResult<out T>
data class Success<T>(val data: T) : NetworkResult<T>()
data class Error(val message: String) : NetworkResult<Nothing>()
object Loading : NetworkResult<Nothing>()

fun handleResult(result: NetworkResult<String>) {
    when (result) {
        is Success -> println("Данные: ${result.data}")
        is Error -> println("Ошибка: ${result.message}")
        Loading -> println("Загрузка...")
        // Компилятор знает, что все случаи обработаны
    }
}

Если добавить новый наследник sealed class, компилятор автоматически укажет на необходимость обновить все when-выражения.

2. Гибкость структуры данных

В отличие от enum, каждый наследник sealed class может иметь различные свойства и методы:

sealed class UIElement {
    data class Button(val text: String, val onClick: () -> Unit) : UIElement()
    data class TextField(val value: String, val hint: String) : UIElement()
    data class Image(val url: String, val width: Int, val height: Int) : UIElement()
    // Каждый тип имеет свою уникальную структуру
}

3. Типобезопасность

Запечатанные классы обеспечивают безопасность типов на уровне компиляции. Вы не можете случайно создать необработанный подтип где-то ещё в коде.

4. Улучшенная читаемость кода

Явное объявление всех вариантов в одном месте делает код более самодокументируемым и понятным для других разработчиков.

Практический пример: обработка состояний ViewModel

sealed class LoginState {
    object Idle : LoginState()
    object Loading : LoginState()
    data class Success(val user: User) : LoginState()
    data class Error(val errorCode: Int, val message: String) : LoginState()
}

class LoginViewModel : ViewModel() {
    private val _state = MutableStateFlow<LoginState>(LoginState.Idle)
    val state: StateFlow<LoginState> = _state.asStateFlow()
    
    fun login(username: String, password: String) {
        _state.value = LoginState.Loading
        
        viewModelScope.launch {
            try {
                val user = repository.login(username, password)
                _state.value = LoginState.Success(user)
            } catch (e: Exception) {
                _state.value = LoginState.Error(500, e.message ?: "Unknown error")
            }
        }
    }
}

В UI-слое можно безопасно обрабатывать все состояния:

viewModel.state.collect { state ->
    when (state) {
        is LoginState.Idle -> showLoginForm()
        is LoginState.Loading -> showProgressBar()
        is LoginState.Success -> navigateToHome(state.user)
        is LoginState.Error -> showErrorDialog(state.errorCode, state.message)
    }
}

Отличия от enum class

Хотя оба представляют ограниченные наборы значений, ключевые отличия:

  • Enum — каждый элемент является одиночным экземпляром (синглтоном)
  • Sealed class — каждый наследник может иметь множество экземпляров с разными данными
  • Sealed class поддерживает разные типы данных у разных наследников

Заключение

Sealed class в Kotlin — это мощный инструмент для создания типобезопасных, расширяемых и поддерживаемых иерархий классов. Они сочетают преимущества полиморфизма с безопасностью перечислений, предоставляя компилятору достаточно информации для статической проверки полноты обработки всех вариантов. Это делает их особенно ценными в современных подходах к разработке под Android, таких как MVVM и MVI, где управление состоянием играет критически важную роль.

Что такое sealed class в Kotlin? Для чего используется и в чём преимущество? | PrepBro