Kotlin Sealed Classes

Having gone through the concepts of classes in Kotlin, we understand that classes form the basis for any OOP’s oriented language and Kotlin is no different. As evident from the name itself, Sealed Classes are the classes which are closed or sealed, which makes their usage restricted.

The purpose of the sealed classes are for representation of restricted class hierarchies when the value or object can have its type from a limited set, but cannot have any other type. To put in simple words, sealed classes can be taken as extension of enum. To learn about enum, click <link of enum>. The type of enum is restricted, and each of these enum constant should exist as a single instance. But in case of sealed classes, you can hold multiple instances of subclass which can further contain multiple states.

Kotlin Sealed Classes

To declare a sealed class, we can simply do it by adding “sealed” modifier before the name of the class.

Syntax:

sealed class Cls{
    // Body of the class goes here.
}

Subclasses:

Sealed classes can have subclass. The only condition to have sub classes is that these must be declared in the same file as the sealed class. Important thing to note in the sealed class is that these can’t be instantiated or in simple words “Sealed classes are Abstract by default.”

For the above sealed class A, if you wish to instantiate, we would get an error:

fun main(args: Array<String>) 
{
    var obj = Cls() //class Cls cannot be instantiated hence would give Compilation error
}

Since the sealed classes are abstract by default, hence can’t be instantiated and can hold abstract methods.

Lets see how a class with sub class would look like:

sealed class Cls{
    class X : Cls()
    class Y : Cls()
}

The above code would work, without any issues since sub classes are allowed in sealed classes. An interesting observation here is the fact that classes which extend subclasses of the sealed class (classes inherited indirectly) can be placed anywhere and needs not to be mandatorily created in same file.

sealed class X{
    class Y : X() 
    {
        class XY : X() // Working Code.
    }
    class Z : X()
    init {
        println("sealed class A")
    }
}

class AnotherClass : A() // Working Code
{
class XClass : A() //Since, sealed class need to be in the same scope, this won’t work.
 }

The above example clears the fact that classes which extend subclasses of the sealed class (classes inherited indirectly) can be placed anywhere and needs not to be mandatorily created in same file.

Constructors in Sealed Classes

By default the constructor of sealed classes are private. No constructor in sealed class can be non-private.

Let’s see some illustrations to understand the working of constructors in sealed class:

sealed class X(var name: String){
    class Y : X("Y")
    class Z : X("Z")
}
class Q : X("Q")

fun main(args: Array<String>) {
    
    var y = A.Y()
    var q = Q()
}

Adding Data Class and Object in a sealed class.

fun main(args: Array<String>) {
    val e = A.E("Anupam")
    println(e) //prints E(name=Anupam)

    var d = A.D
    d.name() //prints Object D
}

Difference between Enum and Sealed Classes

In Kotlin, Sealed Classes are termed as extension of Enums. The use case of sealed classes is to create instances with different types, whereas Enum type restrict the creation of same type for all enum constants.

Lets take an enum of days of week and try to understand:

enum class Days(string: String){
Monday("Mon"), Tuesday(2), // This is not possible in enums
}

The above creation is not allowed in enums as enums allow only single type for all the constants. Now follow the example below to how sealed classes helps us solve the above issue by allowing the multiple instances.

sealed class Days {
    class Monday (var abr: String) : Days ()
    class Tuesday (var seq: Int) : Days ()
    class Wednesday (var abr: String, var seq: Int) : Days ()
}

Use case of Heterogeneous type of objects in Real Projects

Lets take an example you are building a blog application which will can have three different types of posts:

  1. Text Post
  2. Image & Text Post
  3. Video, Image & Text Post
sealed class BlogPost
{
    class TextPost(var text: String) : BlogPost ()
    class ITPost(var url: String, var text: String) : BlogPost ()
    class VITPost(var VUrl: String, var IUrl: String, var text: String): BlogPost ()
}

The above example is not possible without the presence of sealed classes in Kotlin.

With this we have understood the use cases of the sealed classes and how the ability to store heterogeneous objects helps to create a new avenue of development.

Leave a Comment