Перечисление фиксированного набора констант, где каждая константа существует в единственном экземпляре.
enum class Color {
RED, GREEN, BLUE
}
Ограниченная иерархия классов, где все возможные подтипы известны на этапе компиляции.
sealed class Result<out T> {
data class Success<T>(val data: T) : Result<T>()
data class Error(val message: String) : Result<Nothing>()
object Loading : Result<Nothing>()
}
Характеристика | Enum Class | Sealed Class |
---|---|---|
Тип элементов | Одиночные константы (синглтоны) | Полноценные классы с разной структурой |
Состояние | Одно на весь enum | Уникальное для каждого подкласса |
Данные | Могут иметь общие свойства | Каждый подкласс свои данные |
Методы | Общие для всех элементов | Индивидуальные для каждого подтипа |
Иерархия | Одноуровневая | Многоуровневая |
Generics | Не поддерживаются | Полная поддержка |
Использование в when | Проверка всех случаев (exhaustive) | Также exhaustive проверка |
enum class DeliveryStatus {
PENDING, PROCESSING, SHIPPED, DELIVERED
}
enum class Direction(val degrees: Int) {
NORTH(0), EAST(90), SOUTH(180), WEST(270)
}
sealed class PaymentResult {
data class Success(val txId: String) : PaymentResult()
data class Error(val code: Int, val message: String) : PaymentResult()
object Pending : PaymentResult()
}
sealed class UiState {
object Loading : UiState()
data class Content(val items: List<Item>) : UiState()
data class Error(val cause: Throwable) : UiState()
}
Enum - все экземпляры одинаковы:
enum class NetworkState(val isConnected: Boolean) {
CONNECTED(true),
DISCONNECTED(false)
}
Sealed Class - разное состояние для каждого типа:
sealed class NetworkState {
data class Connected(val speed: Int) : NetworkState()
object Disconnected : NetworkState()
}
Enum - закрыт для расширения:
// Нельзя добавить новые элементы в runtime
Sealed Class - позволяет добавлять поведение:
sealed class Animal {
abstract fun makeSound()
class Dog : Animal() {
override fun makeSound() = println("Woof!")
}
// Можно добавить Cat позже в том же файле
}
Интересный паттерн - комбинация enum и sealed class:
enum class ApiStatus { SUCCESS, ERROR }
sealed class ApiResult<out T> {
data class Success<T>(val data: T) : ApiResult<T>()
data class Error(val exception: Exception) : ApiResult<Nothing>()
fun toStatus() = when(this) {
is Success -> ApiStatus.SUCCESS
is Error -> ApiStatus.ERROR
}
}
Выбирайте Enum, когда:
Выбирайте Sealed Class, когда:
Общие черты:
Используйте правильный инструмент в зависимости от требований к гибкости и сложности моделируемой предметной области.