Show how a Kotlin enum can implement multiple interfaces while providing a class-level default that only some constants override. What are the constraints?
answer
- Comma-separated interfaces in header
- Class-level default + per-constant override for exceptions
- Enum can't extend a class — only interfaces
- name/ordinal/compareTo are final
- Interface val via override-in-constructor
basics
~10 sList the interfaces comma-separated after the colon. Implement one as a class-level default that all constants inherit, and override it only in the constants that need different behavior.
solid answer
~40 sAn enum can implement several interfaces: `enum class Color : Describable, Comparable<Color>`. (Comparable is already supplied by the compiler from declaration order, so you usually don't redeclare it.) You provide class-level `override` members that all constants inherit by default, and selectively override in a constant body for exceptions. Constants that don't need special behavior are written with no body and use the default. Constraints: an enum **cannot extend another class** (it implicitly extends `kotlin.Enum`), so only interfaces are allowed as supertypes; you may not override `final` enum members like `name`, `ordinal`, or the auto-generated `compareTo`; and abstract members declared in the enum force every constant to provide a body. Class-level overrides may reference `name`/`ordinal` and other properties.
code
kotlin · 9 linesinterface Describable { fun describe(): String }
interface Priced { val cents: Int }
enum class Plan(override val cents: Int) : Describable, Priced {
FREE(0),
PRO(1900),
ENTERPRISE(0) { override fun describe() = "Custom-quoted" };
override fun describe() = "$name at $cents cents"
}go deeper
Recognizes comma-separated interfaces but may not know the no-class-extension constraint.
Implements multiple interfaces, uses a class-level default with selective per-constant overrides, satisfies interface vals via the constructor.
Articulates the final-member and single-inheritance constraints and why callers should depend on the interface, not the enum.
Designs the abstraction boundary so enums implement domain interfaces, keeping consumers decoupled and exhaustiveness intact.
## Multiple interfaces + selective override An enum lists multiple interfaces comma-separated. You can give a **class-level default** (shared) implementation and **override per-constant** only where needed. ```kotlin interface Describable { fun describe(): String } interface Priced { val cents: Int } enum class Plan(override val cents: Int) : Describable, Priced { FREE(0), PRO(1900), ENTERPRISE(0) { // overrides the default describe() override fun describe() = "Custom-quoted plan" }; override fun describe() = "$name at $cents cents" // class-level default } ``` `FREE.describe()` -> "FREE at 0 cents" (default); `ENTERPRISE.describe()` -> "Custom-quoted plan". ## Key constraints - **No class supertype.** An enum implicitly extends `kotlin.Enum`, so it can only add **interfaces**, never another open class. `enum class X : SomeOpenClass` is a compile error. - **`Comparable` is built in.** The compiler generates `compareTo` from declaration order; `name`, `ordinal`, `values()`/`entries`, `valueOf` are `final` — you cannot override them. - **Abstract members force bodies.** If the enum declares an `abstract fun` (often to satisfy an interface per-constant), *every* constant must supply a body. - **Properties via primary constructor.** Interface `val`s can be satisfied through the primary constructor using `override val` parameters (see `cents` above). ## Why this shape is useful You get one fixed, exhaustive set of values that are simultaneously several abstractions (e.g. both `Describable` and `Priced`). Callers depend on the *interface*, not the enum, keeping coupling low while still benefiting from exhaustiveness in `when`. ## Mixing default and per-constant Provide the common case once at class level; pay the cost of a constant body only for the outliers. This avoids a big `when` and keeps each special case next to its constant.
- Why can't an enum also extend an open class to share state?An enum already extends the implicit `kotlin.Enum` superclass and Kotlin/JVM is single-inheritance, so only interfaces remain available as supertypes.
- How do you satisfy an interface's `val` without a body in each constant?Declare it as an `override val` parameter in the primary constructor and pass the value at each constant declaration.
saying these in an interview costs you the question
- Claiming an enum can extend a base class for shared behavior
- Trying to override name/ordinal/compareTo
- Forgetting some constants can keep the default while others override
- Not knowing Comparable is auto-implemented
- Adding a constant body when the default already suffices