В чем разница между sealed class и enum

Ответ

Sealed class и enum оба ограничивают набор возможных подтипов, но с ключевыми отличиями:

  1. Состояние: Enum константы - синглтоны, а sealed class позволяет создавать множественные экземпляры с разным состоянием.
  2. Гибкость: 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 — это всё-таки гениально и сложно одновременно, ёпта.