0Pricing
Kotlin Academy · Урок

sealed class и sealed interface: когда что использовать

Разберитесь в различиях между запечатанными классами и интерфейсами в Kotlin.

«sealed class и sealed interface: когда что использовать» — бесплатный урок Kotlin Academy на CoddyKit. Это урок 1 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Kotlin Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Kotlin Academy содержит 4 уроков всего.

Запечатанные типы в Kotlin

Запечатанные классы и интерфейсы ограничивают иерархию классов известным набором подтипов, благодаря чему выражения when можно проверять на полноту.

Основы sealed class

Запечатанный класс ограничивает наследование тем же пакетом (начиная с Kotlin 1.5) или тем же файлом.
sealed class Shape
class Circle(val radius: Double) : Shape()
class Rectangle(val w: Double, val h: Double) : Shape()
object Unknown : Shape()

sealed interface: больше гибкости

sealed interface позволяет подтипам одновременно расширять другие классы AND реализовывать другие интерфейсы — sealed class этого не позволяет.
sealed interface Result<out T>
data class Success<T>(val value: T) : Result<T>
data class Error(val ex: Exception) : Result<Nothing>

Ключевые различия

sealed class: у подклассов могут быть конструкторы и состояние. sealed interface: подтипы могут расширять любой класс. Используйте sealed interface, когда Вам нужна большая гибкость.
// sealed class subtype extends another class:
sealed interface Command
class MoveCommand(val dx: Int, val dy: Int) : Command, Serializable
class ResizeCommand(val scale: Double) : Command, Cloneable

Исчерпывающий when: else не нужен

Если охвачены все запечатанные подтипы, выражение when является исчерпывающим — ветвь else не нужна, а компилятор проверяет полноту.
fun area(shape: Shape): Double = when (shape) {
    is Circle -> Math.PI * shape.radius * shape.radius
    is Rectangle -> shape.w * shape.h
}  // no 'else' — compiler guarantees completeness

Добавление подтипа нарушает существующие when

Добавьте новый запечатанный подтип — и существующие выражения when перестанут компилироваться, пока Вы их не обновите. В этом заключается главное преимущество.
// Add Triangle to Shape:
class Triangle(val base: Double, val height: Double) : Shape()
// Now the area() function above won't compile until
// a Triangle branch is added — safety net!

Запечатанные классы с общими свойствами

Объявляйте общие свойства в запечатанном классе.
sealed class NetworkResult {
    abstract val timestamp: Long
}
data class SuccessResult(val data: String, override val timestamp: Long) : NetworkResult()
data class FailureResult(val error: String, override val timestamp: Long) : NetworkResult()

Вложенные запечатанные типы

Запечатанные подтипы сами могут быть запечатанными, что позволяет создавать многоуровневые иерархии.
sealed interface UiState
object Loading : UiState
sealed interface Loaded : UiState
data class Content(val items: List<String>) : Loaded
data class Empty(val hint: String) : Loaded
data class Failure(val error: String) : UiState

Подтипы object без состояния

Используйте object для запечатанных подтипов, которые не содержат состояния.
sealed class Direction
object North : Direction()
object South : Direction()
object East : Direction()
object West : Direction()

fun move(d: Direction) = when (d) {
    North -> y++
    South -> y--
    East -> x++
    West -> x--
}

Совместное использование sealed, data class и object

Используйте data class для подтипов с состоянием, а object — для одиночных объектов в рамках запечатанного типа.
sealed class LoadState
object Idle : LoadState()
object Loading : LoadState()
data class Success(val count: Int) : LoadState()
data class Error(val msg: String) : LoadState()

Когда выбрать sealed class, а когда interface

Используйте sealed class, если все подтипы имеют общее состояние. Используйте sealed interface, если подтипам нужно расширять разные базовые классы или реализовывать другие интерфейсы.

Быстрая проверка

Какое преимущество sealed interface имеет перед sealed class?

Итоги

sealed class/interface ограничивает иерархию известными типами. when с sealed является исчерпывающим — else не нужен. sealed interface позволяет подтипам расширять другие классы. Используйте data class для подтипов с состоянием, а object — для подтипов без состояния.

Часто задаваемые вопросы

Урок «sealed class и sealed interface: когда что использовать» бесплатный?

Да — полный текст урока «sealed class и sealed interface: когда что использовать» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Kotlin Academy, подпишись на CoddyKit PRO. Курс Kotlin Academy содержит 4 уроков всего.

Чему я научусь в уроке «sealed class и sealed interface: когда что использовать»?

Разберитесь в различиях между запечатанными классами и интерфейсами в Kotlin. Ты практикуешь Kotlin Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать Kotlin Academy?

Предыдущий опыт не требуется. Kotlin Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 1 из 4.

Сколько времени занимает урок «sealed class и sealed interface: когда что использовать»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке Kotlin Academy?

Да. Каждый урок Kotlin Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. sealed class и sealed interface: когда что использовать
  2. Полное when с запечатанными иерархиями
  3. Моделирование состояния интерфейса с помощью запечатанных классов
  4. Вложенные и объединённые запечатанные иерархии
← Назад к Kotlin Academy