Inheritance, Interfaces & Sealed Types

open and abstract classes, interfaces, overriding, and sealed hierarchies with exhaustive when.

Kotlin classes are final unless marked open, which avoids fragile inheritance. Interfaces can contain default implementations, and sealed types define closed hierarchies that the compiler can check exhaustively — ideal for states, messages and results.

Devices and CAN frames

Device is abstract and implements Describable; powerMw is open, so subclasses may override it.

Motor overrides powerMw; TempSensor keeps the default.

sealed interface Frame lists every possible frame type.

when (f) covers all four subtypes, so no else branch is needed; is DataFrame smart-casts f.

data object OverloadFrame is a singleton with a readable toString.

class Base { fun f() = 1 } class Derived: Base() // error: Base is final open class Base { open fun f() = 1 } class Derived: Base() { override fun f() = 2 }

Classes and members must be explicitly open to be extended or overridden.

Why use a sealed class/interface instead of an enum?

Each subtype of a sealed hierarchy can hold different data (like DataFrame's bytes), while enum entries share one structure. Both allow exhaustive when.