Данные в вариантах sealed class в Kotlin
Подтип запечатанного класса часто объявляют как
data class, если у варианта есть поля: работают
те же equals, copy и toString,
что и у отдельного data class, только вариант наследует
запечатанный родитель:
sealed class OrderEvent {
data class Created(val id: Long) : OrderEvent()
data class Paid(val id: Long, val sum: Double) : OrderEvent()
object Cancelled : OrderEvent()
}
fun main() {
val a = OrderEvent.Paid(1, 9.99)
val b = OrderEvent.Paid(1, 9.99)
println(a == b)
}
У data class внутри sealed иерархии можно менять
отдельные поля через copy, не создавая новый
тип вручную:
sealed class Profile {
data class User(val name: String, val age: Int) : Profile()
object Guest : Profile()
}
fun main() {
val u = Profile.User("Ann", 20)
val older = u.copy(age = 21)
println(older)
}
В одной иерархии сочетают data class для вариантов
с данными и object для одиночных состояний.
Разбор в when остается исчерпывающим, если
перечислены все объявленные подтипы:
sealed class Download {
object Idle : Download()
data class Progress(val percent: Int) : Download()
data class Ready(val path: String) : Download()
}
fun label(d: Download): String = when (d) {
Download.Idle -> "idle"
is Download.Progress -> "${d.percent}%"
is Download.Ready -> d.path
}
fun main() {
println(label(Download.Progress(40)))
}
Объявите sealed class Point:
Origin как object,
XY как data class с полями
x и y.
Создайте Point.XY(2, 3), получите копию
с y = 5 и выведите ее.
Объявите sealed class Note:
Blank как object,
Text как data class с полем
body: String.
Даны значения:
val first = Note.Text("hi")
val second = Note.Text("hi")
Выведите true, если они равны,
иначе false.