В чем преимущество sealed классов перед enum
Что проверяют
Понимаете ли вы, что enum это фиксированный набор экземпляров одной формы, а sealed это закрытая иерархия типов, где каждый вариант несёт свои данные. Следом обычно спрашивают, где вы применяете sealed в проекте и когда enum всё-таки лучше.
Как отвечать
Общее у них одно: компилятор знает все варианты, поэтому when без else исчерпывающий. Добавили новый вариант, и каждый такой when перестанет компилироваться, пока его не обработают. С Kotlin 1.7 это требование действует не только для when-выражения, но и для when-оператора по sealed и enum.
Преимущества sealed:
- разные данные у вариантов:
data class Success(val items: List<Item>)иdata class Error(val throwable: Throwable)в одной иерархии. Enum тоже умеет свойства и методы, но набор свойств у всех констант общий; - много экземпляров: константа enum существует в единственном экземпляре, а подклассов sealed можно создать сколько угодно, с разными значениями;
- вложенные иерархии: вариант сам может быть sealed, например
sealed interface Error : UiStateс видами ошибок внутри.
Типичное применение в Android: состояние экрана во ViewModel (Loading, Content, Error), которое отдаётся через StateFlow и разбирается в Compose через when, одноразовые события, результаты сетевых запросов.
Где лучше enum: простые константы без данных, вроде типа сортировки или вкладки. У enum бесплатно есть entries (замена values() с Kotlin 1.9), name, ordinal, valueOf(), он просто сериализуется и работает с EnumMap.
Для вариантов без данных внутри sealed берите data object: у него читаемый toString() вместо имени класса с хэшем.
Где спотыкаются
Говорят, что sealed «расширяемее» enum. Обе конструкции закрыты: прямые подклассы sealed объявляются только в том же модуле и пакете, в этом весь смысл.
Ставят else в when по sealed. Проверка полноты перестаёт работать, и новый вариант молча уходит в ветку по умолчанию.
Тащат sealed туда, где хватило бы трёх констант без данных, или, наоборот, прячут в enum изменяемое состояние, которое оказывается общим на всё приложение.