Sealed classes and interfaces represent restricted class hierarchies that provide more control over inheritance.
All direct subclasses of a sealed class are known at compile time. No other subclasses may appear outside the module and package within which the sealed class is defined. For example, third-party clients can't extend your sealed class in their code. Thus, each instance of a sealed class has a type from a limited set that is known when this class is compiled.
The same works for sealed interfaces and their implementations: once a module with a sealed interface is compiled, no new implementations can appear.
Sealed Classes allow us to fix type hierarchies and forbid developers from creating new subclasses.
A sealed class is abstract by itself, it cannot be instantiated directly and can have abstract members.
As an example, consider a library's API. It's likely to contain error classes to let the library users handle errors that it can throw. If the hierarchy of such error classes includes interfaces or abstract classes visible in the public API, then nothing prevents implementing or extending them in the client code. However, the library doesn't know about errors declared outside it, so it can't treat them consistently with its own classes. With a sealed hierarchy of error classes, library authors can be sure that they know all possible error types and no other ones can appear later.
Sealed classes and when expression
The key benefit of using sealed classes comes into play when you use them in a when expression. If it's possible to verify that the statement covers all cases, you don't need to add an else clause to the statement:
These restrictions don't apply to indirect subclasses. If a direct subclass of a sealed class is not marked as sealed, it can be extended in any way that its modifiers allow:
Kotlin provides an important new type of class that is not present in Java. These are known as sealed classes. As the word sealed suggests, sealed classes conform to restricted or bounded class hierarchies. A sealed class defines a set of subclasses within it. It is used when it is known in advance that a type will conform to one of the subclass types. Sealed classes ensure type safety by restricting the types to be matched at compile-time rather than at runtime.
Their constructors are protected by default.
To define a sealed class, just precede the class modifier with the sealed keyword. The sealed classes also have one another distinct feature, their constructors are protected by default. A sealed class is implicitly abstract and hence it cannot be instantiated.
Use Cases of Sealed Classes
One common use case for sealed classes is to represent the result of an operation. For example, We might define a sealed class called Result with two subclasses: Success and Error.
As of Kotlin 1.5, sealed classes can have subclasses in all files of the same compilation unit and the same package.
Sealed classes can have fields and methods defined in them, including both abstract and implemented functions. This means that we can have a base representation of the class and then adjust it to suit the subclasses.
Anytime we have an unknown number of options, we can not use a sealed class because this will stop us from adding options outside of the original source file.
Enum Vs Sealed
Enum restricts values where as sealed class restricts types.
If there are 3 colours then use enum but each color have multiple types of variant then use sealed
Enum creates single object where as sealed class can create multiple object of single type
sealed is an abstract class
In some sense, sealed classes are similar to enum classes: the set of values for an enum type is also restricted, but each enum constant exists only as a single instance, whereas a subclass of a sealed class can have multiple instances, each with its own state.
When we write when expression with tile type, compiler shows the possible option of red & blue only. so in a way we can restrict the type of tile with red & blue.
Constructors of sealed classes can have one of two visibilities: protected (by default) or private: