kotlinbeginner
Enum Classes — Advanced Patterns
Use Kotlin enum classes with properties, methods, interfaces, and companion utilities.
kotlinPress ⌘/Ctrl + Shift + C to copy
// Basic enum with properties
enum class HttpStatus(val code: Int, val description: String) {
OK(200, "Success"),
CREATED(201, "Created"),
BAD_REQUEST(400, "Bad Request"),
UNAUTHORIZED(401, "Unauthorized"),
NOT_FOUND(404, "Not Found"),
INTERNAL_ERROR(500, "Internal Server Error");
val isSuccess get() = code in 200..299
val isClientError get() = code in 400..499
val isServerError get() = code in 500..599
companion object {
fun fromCode(code: Int): HttpStatus? =
entries.find { it.code == code }
}
}
// Enum implementing interface
interface Printable {
fun display(): String
}
enum class Planet(
val mass: Double, // kg
val radius: Double // meters
) : Printable {
MERCURY(3.303e+23, 2.4397e6),
VENUS(4.869e+24, 6.0518e6),
EARTH(5.976e+24, 6.37814e6),
MARS(6.421e+23, 3.3972e6);
val surfaceGravity get() = G * mass / (radius * radius)
fun surfaceWeight(otherMass: Double) = otherMass * surfaceGravity
override fun display() = "$name (gravity: ${"%,.2f".format(surfaceGravity)} m/s²)"
companion object {
const val G = 6.67300E-11
}
}
// Enum with abstract method
enum class Operation {
ADD {
override fun apply(a: Double, b: Double) = a + b
override val symbol = "+"
},
SUBTRACT {
override fun apply(a: Double, b: Double) = a - b
override val symbol = "-"
},
MULTIPLY {
override fun apply(a: Double, b: Double) = a * b
override val symbol = "×"
},
DIVIDE {
override fun apply(a: Double, b: Double) = if (b != 0.0) a / b else Double.NaN
override val symbol = "÷"
};
abstract fun apply(a: Double, b: Double): Double
abstract val symbol: String
}
fun main() {
// HttpStatus
val status = HttpStatus.NOT_FOUND
println("${status.code}: ${status.description} (client error: ${status.isClientError})")
val found = HttpStatus.fromCode(200)
println("Code 200: $found")
// Iterate
HttpStatus.entries
.filter { it.isSuccess }
.forEach { println(" ${it.code} ${it.name}") }
// Planet
println("\n--- Planets ---")
val earthWeight = 75.0 // kg
Planet.entries.forEach { planet ->
println("${planet.display()} — Weight: ${"%,.1f".format(planet.surfaceWeight(earthWeight))} N")
}
// Operation
println("\n--- Calculator ---")
Operation.entries.forEach { op ->
println("10 ${op.symbol} 3 = ${op.apply(10.0, 3.0)}")
}
// when exhaustive
fun describe(status: HttpStatus): String = when (status) {
HttpStatus.OK, HttpStatus.CREATED -> "Success!"
HttpStatus.BAD_REQUEST -> "Check your request"
HttpStatus.UNAUTHORIZED -> "Please log in"
HttpStatus.NOT_FOUND -> "Resource not found"
HttpStatus.INTERNAL_ERROR -> "Server error"
}
println(describe(HttpStatus.OK))
}Use Cases
- Type-safe constant sets with behavior
- HTTP status code management
- State and operation enumerations
Tags
Related Snippets
Similar patterns you can reuse in the same workflow.
kotlinbeginner
Null Safety — Elvis, Safe Call, and let
Master Kotlin null safety: safe calls, Elvis operator, let/also scoping, and smart casts.
Best for: Safe navigation through nullable chains
#kotlin#null-safety
kotlinbeginner
Data Classes — Copy, Destructure, and Equals
Use data classes for immutable models: auto-generated equals, hashCode, copy, and destructuring.
Best for: Immutable domain models and DTOs
#kotlin#data-class
kotlinbeginner
Scope Functions — let, run, apply, also, with
Master Kotlin scope functions: when to use let, run, apply, also, and with for concise code.
Best for: Object initialization and configuration
#kotlin#scope-functions
kotlinbeginner
Collections — map, filter, groupBy, and More
Master Kotlin collections: functional transformations, aggregations, grouping, and partition operations.
Best for: Data processing and transformation pipelines
#kotlin#collections