In Kotlin, how do you make each enum constant run its own different code for the same operation? Show a small example.
answer
- abstract member in the enum
- override in braces after each constant
- semicolon ends the constant list
- each constant = anonymous subclass
- type-safe strategy, no when chain
basics
~10 sDeclare an abstract function in the enum, then give each constant a body in curly braces that overrides it. Calling the function on a constant runs that constant's version.
solid answer
~40 sDefine an `abstract` member (function or property getter) in the enum class body. Each constant then supplies its own implementation in an anonymous-class body — the braces right after the constant's name, with the function marked `override`. Each constant is effectively a tiny subclass of the enum type that fills in the abstract member. Calling the member dispatches to the matching constant's override at runtime, so `Operation.PLUS.apply(2, 3)` and `Operation.TIMES.apply(2, 3)` run different code. This is the type-safe strategy pattern: the compiler forces every constant to implement the abstract member, so you can never forget one, and there is no `when`/`if` chain to maintain.
code
kotlin · 12 linesenum class Operation {
PLUS { override fun apply(a: Int, b: Int) = a + b },
MINUS { override fun apply(a: Int, b: Int) = a - b },
TIMES { override fun apply(a: Int, b: Int) = a * b };
abstract fun apply(a: Int, b: Int): Int
}
fun main() {
println(Operation.PLUS.apply(4, 2)) // 6
println(Operation.TIMES.apply(4, 2)) // 8
}go deeper
Can write the abstract function plus per-constant override and explain that each constant runs its own code.
Explains the semicolon rule and that each constant is an anonymous subclass with virtual dispatch.
Frames it as the type-safe strategy pattern and contrasts with when, noting compile-time exhaustiveness.
Discusses when per-constant bodies hurt (generated class bloat, testing) vs centralized strategy, and migration tradeoffs.
## The idea An **enum class** is a fixed set of named constants. Normally every constant behaves identically. "Enums with behavior" means each **constant** carries its *own* implementation of a shared operation. ## The mechanism: abstract member + per-constant body You declare an `abstract` function (or `abstract val` with a custom getter) inside the enum body. Because it is abstract it has no implementation there — so **each constant must provide one**. A constant provides it by writing an **anonymous-class body**: open curly braces right after the constant name and `override` the member. ```kotlin enum class Operation { PLUS { override fun apply(a: Int, b: Int) = a + b }, TIMES { override fun apply(a: Int, b: Int) = a * b }; abstract fun apply(a: Int, b: Int): Int } val r = Operation.TIMES.apply(2, 3) // 6 ``` Key syntax points: - The constant list ends with a **semicolon (`;`)** before any members are declared. This semicolon is mandatory when the enum has a body. - Each `{ ... }` after a constant is an **anonymous subclass** of the enum type. Under the hood the compiler generates a synthetic class per such constant. - Every constant must override every abstract member, or the code does not compile — that is the "type-safe" guarantee. ## Why this over `when` A `when (this)` inside one shared function also works, but: - The compiler does **not** force you to handle a newly added constant unless the `when` is exhaustive *and* used as an expression. - Behavior is scattered or centralized away from the constant. The per-constant body keeps each constant's logic next to its name. ## Dispatch Calling `someConstant.apply(...)` uses normal virtual dispatch: the runtime type is the synthetic subclass for that constant, so its `override` runs. This is **polymorphism**, just with a closed, finite set of subtypes. ## Related keywords `enum class`, `abstract`, `override`, anonymous-class body, the constant-list-terminating `;`.
- What happens if you add a constant but forget to override the abstract function?It does not compile — the new constant's anonymous body must implement every abstract member, so the compiler flags it immediately.
- Why is the semicolon after the last constant required here?Because the enum has further members (the abstract function); the `;` separates the constant list from those member declarations.
Each constant is a vending-machine slot that holds its own recipe; pressing the slot runs that recipe.
saying these in an interview costs you the question
- Thinking you must use a giant when(this) instead of per-constant bodies
- Forgetting the mandatory semicolon after the constant list
- Saying enums cannot have abstract methods
- Believing the constant body is a lambda rather than an anonymous subclass
- Not marking the per-constant function override