Ответ
Sealed class и enum оба ограничивают набор возможных подтипов, но с ключевыми отличиями:
- Состояние: Enum константы - синглтоны, а sealed class позволяет создавать множественные экземпляры с разным состоянием.
- Гибкость: Sealed class поддерживает разные параметры и методы для каждого подкласса, enum ограничен фиксированными значениями.
Пример:
sealed class Result {
data class Success(val data: String) : Result()
data class Error(val message: String) : Result()
}
enum class Status {
SUCCESS, ERROR // Без состояния
}
Sealed class лучше для сложных иерархий с данными, enum - для простых фиксированных значений.
Ответ 18+ 🔞
Давай разберёмся, что к чему, а то у меня уже глаза на лоб лезут от этих sealed class и enum. Сижу тут, кофе холодный, думаю — ёпта, опять эти умные слова, которые все используют, а толком не понимают, в чём прикол.
Смотри, оба этих типа — они как бы ставят забор: «Дальше, блядь, не ходи, подтипов больше не будет». Но заборы-то разные, понимаешь?
Первое — про состояние. Вот представь себе enum. Это как будто ты пришёл в столовую, а там меню: «Компот», «Кисель», «Морс». И всё. Ты не можешь сказать: «Дайте мне компот, но чтобы он был с кусочками яблока и мятой». Нет, сука, компот — он и есть компот. Константа, синглтон, один на всех. А sealed class — это уже как ресторан. Ты заказываешь «суп», но суп-то может быть куриный с лапшой, а может быть грибной с картошкой. И у каждого своё состояние, свои данные внутри. Можно хоть десять разных успешных результатов наклепать, и все будут разными объектами. Вот в чём, блядь, разница!
Второе — гибкость, или её отсутствие. С enum'ом ты сильно не разбежишься. Значения фиксированные, параметры к ним не особо прикрутишь (ну, кроме какого-нибудь примитивного свойства). А sealed class — это же просто песня! Каждый наследник — это полноценный класс. Можешь туда какие угодно поля пихать, методы свои городить. Получается такая хитрая, но контролируемая иерархия. Удивление пиздец, как удобно.
Смотри на примере, тут всё станет ясно. Допустим, у тебя есть результат какой-то операции.
Вот как это выглядит на sealed class:
sealed class Result {
data class Success(val data: String, val code: Int) : Result() // Один тип успеха
data class PartialSuccess(val warning: String) : Result() // Другой тип успеха, с предупреждением!
data class Error(val message: String, val exception: Throwable?) : Result() // А тут уже ошибка с подробностями
}
Видишь? Success и PartialSuccess — оба успехи, но состояния у них овердохуища разные. В один можно кучу данных запихнуть, в другой — предупреждение. И все они — Result.
А теперь смотри на enum:
enum class Status {
SUCCESS, ERROR // И всё, брат. Без состояния. Просто флажки.
}
Ну что это такое? «Успех». А какой успех? Что за данные? Хуй с горы, просто успех. Для простых случаев — огонь, но если нужно что-то посерьёзнее — сразу чувствуешь, что терпения ноль, ебать.
Итог, чтобы не запутаться:
- Enum — это когда у тебя список фиксированных, простых как три копейки значений. Дни недели, статусы заказа («создан», «оплачен», «отправлен»), цвета светофора. Всё, больше ничего не надо.
- Sealed class — это когда тебе нужна не просто метка, а целая структура с данными внутри. Разные виды успешных ответов от API, разные типы ошибок (сетевая, валидации, серверная), узлы AST в парсере. Вот тут она, блядь, раскрывается во всей красе.
Короче, выбирай по ситуации. Для сложных иерархий с данными — sealed class, мой друг. Для простых фиксированных значений — enum, и не еби себе мозг. Всё гениальное — просто, но sealed class — это всё-таки гениально и сложно одновременно, ёпта.