ProgrammingAndroid/Kotlin Developer

What are sealed interfaces in Kotlin, how and why to use them?

Pass interviews with Hintsage AI assistant

Answer.

Sealed interface is a special type of interface in Kotlin that allows restricting the set of its implementations within a single module. Sealed classes first appeared in Kotlin earlier, and sealed interfaces were introduced starting from Kotlin 1.5 as an evolution for greater control over types involved, for example, in state hierarchies or event handling.

Background

Previously, developers used sealed classes to restrict inheritance and create safe hierarchies. However, for flexibility and support of structures where inheritance from multiple types is beneficial, sealed interfaces were needed.

Problem

Without sealed interfaces, it is not possible to flexibly manage the set of subclasses of an interface. This makes exhaustive when checks impossible when handling states if everything is built on interfaces rather than just abstract/concrete classes.

Solution

Using sealed interface allows:

  • Describing a fixed set of implementations.
  • Ensuring that all implementations are known to the compiler.
  • Safely using when without an else branch — the compiler will warn about unhandled cases.

Code example:

sealed interface Event class Click : Event class Scroll : Event fun handle(event: Event) = when(event) { is Click -> println("Click event") is Scroll -> println("Scroll event") }

Key features:

  • Narrowing and controlling the set of allowable implementations.
  • Ability to inherit from multiple sealed interfaces at the same time.
  • Safety in pattern matching (when).

Trick questions.

Can sealed interfaces have implementations outside the file of their declaration?

No, implementations of a sealed interface must reside in the same module. This provides full exhaustiveness and allows the compiler to control their quantity.

How do sealed interfaces interact with classes and objects?

A sealed interface can be implemented by both regular classes and object classes, as well as data objects (Kotlin 1.9+). Such an interface can be present in multiple inheritance, which cannot be done with sealed classes.

sealed interface Operation object Add: Operation object Subtract: Operation

Can sealed interfaces be nested?

Yes, a sealed interface can be declared inside another sealed class as well as on top of other interfaces. The main condition is that all implementations are within the same module.

Common mistakes and anti-patterns

  • Defining implementations of a sealed interface across different modules leads to compilation errors.
  • Attempting to use a sealed interface based on the assumption that it is like a sealed class, when a sealed interface can be inherited by other interfaces.

Real-life example

Negative case

In an application, UI states were described simply as interfaces without the sealed modifier. One implementation was forgotten, and static analysis did not catch this; the error surfaced only in production.

Pros:

  • Familiar Java-interface pattern.

Cons:

  • No guarantees of exhaustiveness in when.
  • Vulnerability to implementations "from the outside".

Positive case

Using a sealed interface for the screen event model. All implementations are within a single module file, and the compiler notifies of unclosed branches when a case is missed in when.

Pros:

  • Full type-safety.
  • Convenient support and extension.

Cons:

  • Limited use within a single module.