Sealed interfaces are a relatively new feature in Kotlin (since version 1.5), designed to restrict the set of implementations of an interface within a single file. Originally, Kotlin had sealed classes, which provide strict control over the inheritance hierarchy, making exhaustive handling easier (for example, in when expressions).
The problem was that sometimes the architecture required not a base class but an interface with the same limitation on the number of implementations. Before the advent of sealed interfaces, the only way to fit into the compiler's constraints was to use a sealed class, which did not always fit well into the domain model, especially when multiple inheritance or behavior decomposition into interfaces was necessary.
The solution: Sealed interfaces allow you to define an interface whose all implementations must be declared within a single file. This increases code safety and makes it easier to control and navigate through the states or events hierarchy.
Code example:
sealed interface NetworkState class Success(val data: String) : NetworkState class Error(val code: Int) : NetworkState object Loading : NetworkState
Key features:
Can a sealed interface be implemented outside the file where it is declared?
No. Just like sealed classes, sealed interfaces can only be implemented in the same file where they are declared. Trying to implement such an interface outside the file will result in a compilation error.
Can a sealed interface inherit from a class?
No, interfaces can only inherit from other interfaces. However, a sealed interface can inherit from another (sealed) interface.
Does a sealed interface support multiple implementations?
Yes, a class within the same file can implement multiple sealed interfaces or even inherit from a sealed interface and a sealed class simultaneously if allowed by language rules.
In a system for processing network events, a developer uses regular interfaces and sealed classes mixed together, resulting in a "dirty" hierarchy and code duplication. When expressions are forced to contain an else branch.
Pros:
Cons:
In the same application, they switch to a sealed interface NetworkEvent, placing all implementations in one file. Now when expressions over NetworkEvent require handling of all cases. The code becomes more readable, maintainable, and safe.
Pros:
Cons: