Чем sealed классы отличаются от enum?

Часто задают такой вопрос на собеседованиях и многие затрудняются ответить. Я не познал еще в полной мере мощь seald классов, хоть и использовал их. Я знаю, что enum - это перечисления, а по поводу seald классов у меня размытое понятие. Читал документацию и там все крайне мутно,по крайней мере для джунов.


Ответы (1 шт):

Автор решения: Komdosh

Enum классы представляют собой определённый набор значений. Они могут содержать как переменные и даже методы, однако они всё равно представляют именно значения, например дни недели, целочисленные часы работы организации, типы фруктов, которые продаются в магазине. В тоже время enum могут хранить только статические переменные.

enum class Weekday(val someVariable: Int){
 Monday(4){
    override fun generatePhrase() {
       println("Oh it is Monday, num is $someVariable")
    }
 },
 Tuesday(5){
    override fun generatePhrase() {
       println("Today is Tuesday, num is $someVariable")
    }
 };

 abstract fun generatePhrase()
}


fun main() {
    val w = Weekday.Monday
    w.generatePhrase()
}

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

sealed class Auto
data class Tesla(val cost: Int, val batteryCapacity: Int): Auto()
data class Mercedes(val cost: Int, val fuelTank: Int): Auto()
data class Toyota(val cost: Int, val fuelTank: Int): Auto()

fun main() {
    var auto = Tesla(60000, 2000)
    autoSelector(auto)
}

fun autoSelector(auto: Auto){
        when(auto){
        is Tesla -> {
            println("Tesla cost is ${auto.cost} for long trip we have ${auto.batteryCapacity} battery capacity")
        }
        is Mercedes -> {
            println("Mercedes cost is ${auto.cost} for long trip we have ${auto.fuelTank} fuel tank")
        }
        is Toyota -> {
            println("Toyota cost is ${auto.cost} for long trip we have ${auto.fuelTank} fuel tank")
        }
    }
}

В итоге:

  • enum это набор значений, в то время как sealed это набор классов.
  • У enum есть важное преимущество над sealed, они по умолчанию пригодны для сериалиазции и десериализации, когда для sealed классов надо реализовывать методы.
  • sealed классы могут хранить переменные в инстансе объекта, когда enum хранит только статические данные
→ Ссылка