skip to content

How does a Kotlin enum class implement an interface, and how can the implementation differ per enum constant?

level: juniorimportance: must knowfreq 55%

answer

  1. Colon in header lists interfaces
  2. Class-level override = shared; constant body = per-constant
  3. Constant body makes an anonymous subclass
  4. Semicolon separates constants from members
  5. Comma-separate multiple interfaces

basics

~10 s

Put the interface name after a colon in the enum header. You can implement the interface once for all constants, or let each constant override the method with its own version inside its body.

solid answer

~40 s

An enum class declares interfaces in its header just like a normal class: `enum class Op : Calc`. You then satisfy the interface either (1) once at the enum-class level, so every constant shares the same implementation, or (2) per constant, by giving each constant a body (`PLUS { override fun apply(...) = ... }`) that overrides the member. Constant bodies make each constant an anonymous subclass of the enum, so they can supply different behavior. You can mix both: provide a default at the class level and override only in some constants. The enum can implement multiple interfaces, separated by commas. Constants must come first, then a semicolon separates them from the rest of the body (functions, properties, class-level overrides).

code

kotlin · 12 lines
kotlin
interface Op { fun apply(a: Int, b: Int): Int }

enum class Arith : Op {
    PLUS  { override fun apply(a: Int, b: Int) = a + b },
    MINUS { override fun apply(a: Int, b: Int) = a - b };
}

fun main() {
    val r: Op = Arith.PLUS
    println(r.apply(7, 4)) // 11 (PLUS adds)
    println(Arith.MINUS.apply(7, 4)) // 3 (MINUS subtracts)
}

go deeper

for a junior

Knows the colon syntax and that an enum can implement an interface with a single shared override.

for a middle

Can choose between class-level and per-constant overrides and explains the semicolon rule.

for a senior

Explains each constant becomes an anonymous subclass and when to mix default + per-constant overrides.

for a principal

Frames enum+interface as a type-safe, exhaustive-when alternative to int-tag dispatch and weighs it against sealed types.

## What this is A Kotlin `enum class` is a special class with a fixed set of instances (the *constants*). Like any class it can implement one or more **interfaces** (a contract of methods/properties with no state of its own). You declare them in the header after a colon. ## Two ways to satisfy the interface ### 1. Class-level (shared) implementation The enum class provides one `override` and every constant inherits it. ```kotlin interface Named { val label: String; fun describe(): String } enum class Planet : Named { EARTH, MARS; override val label get() = name.lowercase() override fun describe() = "Planet $label" } ``` Here `EARTH.describe()` and `MARS.describe()` run the same code. ### 2. Per-constant implementation Each constant gets a **body** (`{ ... }`) and overrides the member itself. Internally each such constant becomes an **anonymous subclass** of the enum, so each can behave differently. ```kotlin interface Op { fun apply(a: Int, b: Int): Int } enum class Arith : Op { PLUS { override fun apply(a: Int, b: Int) = a + b }, TIMES { override fun apply(a: Int, b: Int) = a * b }; } ``` `Arith.PLUS.apply(2,3)` is 5, `Arith.TIMES.apply(2,3)` is 6. ## Syntax rules to remember - Constants are listed **first**. A **semicolon** (`;`) ends the constant list before any other members or class-level overrides. - A constant body is the block after the constant name; it may override `abstract` members of the enum or interface members. - An enum can implement **multiple** interfaces: `enum class X : A, B { ... }`. - You can mix styles: give a class-level default and override it only in selected constants. ## Why use it It couples a fixed set of named values with polymorphic behavior — a type-safe alternative to a `when` over an int constant. Each constant is still a singleton object, so identity (`===`) and `when` exhaustiveness still work.

  • Where must the semicolon go and why is it required here but optional in a simple enum?
    Right after the last constant, before any functions, properties, or overrides. It's required whenever the enum has body members beyond the constants; a constant-only enum can omit it.
  • Can different constants override the same interface method differently?
    Yes — that's the whole point of per-constant bodies; each constant is an anonymous subclass with its own override.

Each enum constant is a pre-built singleton; giving it a body is like handing that one singleton a custom job description that overrides the company default.

saying these in an interview costs you the question

  • Thinking an enum cannot implement interfaces at all
  • Forgetting the semicolon after the constant list
  • Believing all constants must share one implementation
  • Putting class-level functions before the constants
  • Confusing implementing an interface with extending a class (enums can't extend classes)

context