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

Какие знаешь конструкторы у Sealed Class?

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

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

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

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

Конструкторы Sealed Class в Kotlin

Sealed class (запечатанный класс) в Kotlin может иметь конструкторы, но с определенными ограничениями, которые напрямую следуют из их предназначения - представлять ограниченную иерархию классов, когда все возможные подтипы известны на этапе компиляции.

Основные варианты конструкторов

1. Основной конструктор (Primary Constructor)

Sealed class может иметь первичный конструктор, который автоматически наследуется всеми его подклассами. Это особенно полезно для передачи общих параметров:

sealed class Result<out T : Any>(val data: T?, val error: Throwable?) {
    object Loading : Result<Nothing>(null, null)
    data class Success<T : Any>(val resultData: T) : Result<T>(resultData, null)
    data class Error(val exception: Throwable) : Result<Nothing>(null, exception)
}

2. Конструктор без параметров

Наиболее распространенный случай - sealed class без параметров, когда подклассы сами определяют свою структуру данных:

sealed class PaymentMethod {
    object Cash : PaymentMethod()
    data class CreditCard(val number: String, val expiry: String) : PaymentMethod()
    data class PayPal(val email: String) : PaymentMethod()
}

3. Модификаторы доступа конструктора

Конструктор sealed class всегда имеет модификатор protected (по умолчанию) или private:

// protected конструктор (явно или неявно)
sealed class NetworkState protected constructor()

// private конструктор
sealed class DatabaseOperation private constructor()

Ограничения и особенности

Модификаторы доступа

  • Конструкторы sealed class не могут быть public или internal
  • Это ограничение логично, так как sealed class предназначены для наследования только внутри своего файла (до Kotlin 1.5) или модуля

Наследование конструкторов

Все подклассы sealed class должны явно или неявно вызывать конструктор родительского sealed class:

sealed class Expression {
    abstract fun evaluate(): Double
    
    // Подкласс без собственных параметров
    object Pi : Expression() {
        override fun evaluate(): Double = Math.PI
    }
    
    // Подкласс с параметрами
    data class Sum(val left: Expression, val right: Expression) : Expression() {
        override fun evaluate(): Double = left.evaluate() + right.evaluate()
    }
    
    // Подкласс, использующий параметры родителя
    data class Constant(val value: Double) : Expression() {
        override fun evaluate(): Double = value
    }
}

Data class подклассы

Когда подклассы sealed class объявляются как data class, они получают автоматически сгенерированные методы и должны правильно передавать параметры в родительский конструктор:

sealed class UIEvent {
    data class Click(val x: Int, val y: Int) : UIEvent()
    data class Swipe(val direction: Direction) : UIEvent()
    object BackPress : UIEvent()
}

Практическое применение с параметризованными конструкторами

sealed class ApiResponse<out T>(val timestamp: Long = System.currentTimeMillis()) {
    data class Success<out T>(val data: T, val code: Int) : ApiResponse<T>()
    data class Error(val message: String, val errorCode: Int) : ApiResponse<Nothing>()
    object Loading : ApiResponse<Nothing>()
    
    // Все подклассы получают timestamp от родителя
}

// Использование
fun handleResponse(response: ApiResponse<String>) {
    println("Response at ${response.timestamp}")
    when (response) {
        is ApiResponse.Success -> println("Data: ${response.data}")
        is ApiResponse.Error -> println("Error: ${response.message}")
        ApiResponse.Loading -> println("Loading...")
    }
}

Важные нюансы

  1. Инициализация блока init - Sealed class может содержать блоки init, которые выполняются при создании любого подкласса:
sealed class State {
    init {
        println("State initialized")
    }
    
    object Idle : State()
    data class Active(val value: Int) : State()
}
  1. Вторичные конструкторы - Sealed class поддерживает вторичные конструкторы с теми же ограничениями по видимости:
sealed class Configuration {
    constructor(name: String) {
        // инициализация
    }
    
    constructor(name: String, priority: Int) : this(name) {
        // дополнительная инициализация
    }
}
  1. Совместимость с enum - В отличие от enum, sealed class позволяют создавать экземпляры с различными данными, сохраняя при этом ограниченную иерархию.

Выводы

Конструкторы sealed class в Kotlin обеспечивают баланс между гибкостью наследования и контролем над иерархией. Они позволяют:

  • Определять общие параметры для всех подклассов
  • Сохранять инкапсуляцию через protected/private конструкторы
  • Создавать сложные иерархии типов с гарантией компилятора о полноте when-выражений
  • Эффективно моделировать алгебраические типы данных

Понимание работы конструкторов sealed class критически важно для создания типобезопасных, расширяемых и поддерживаемых архитектур в Kotlin-приложениях.

Какие знаешь конструкторы у Sealed Class? | PrepBro