NashTech Blog

Table of Contents
blockchain, people, shaking hands-2850276.jpg

In Java and Kotlin, there are three renowned types of classes:

  • Open class: can be inherited by any class based on the specified access modifier.
  • Abstract class: must be inherited.
  • Final class: cannot be inherited.

But if we want a way between these, Sealed class is the right choice. Sealed class provide inheritance for limited classes only.  The concept of sealed class is officially introduced in Java 17 LTS version. But for Kotlin, it was added long before. In this article, we will see this feature for both the languages: Java and Kotlin.

Kotlin

In Kotlin, sealed class needs to have the sealed modifier and they can be extended in two ways: 

Direct subclasses defined in the same file as the sealed class

Extend the class outside the sealed class. But no other subclasses should appear outside the module and package within which the sealed class is defined. 

// Define the sealed class
sealed class Automobile(){
    open fun printMessage(){
        println("It's an Automobile.")
    }
}
// Define the subclasses
sealed class Car() : Automobile(){
    override fun printMessage(){
        println("It's a Car.")
    }
}
open class Bus() : Automobile(){
    override fun printMessage(){
        println("It's a Bus.")
    }
}
class Truck() : Automobile(){
    override fun printMessage(){
        println("It's a Truck.")
    }
}
fun main() {
    val bus: Automobile = Bus()
    val truck: Automobile = Truck()
    bus.printMessage()
    truck.printMessage()
}

Nested classes within the sealed class itself

  • Extends the class inside the sealed-class.
// Define the sealed class
sealed class Automobile(){
    open fun printMessage(){
        println("It's an Automobile.")
    }

    // Define the subclasses
    sealed class Car() : Automobile(){
        override fun printMessage(){
            println("It's a Car.")
        }
    }
    open class Bus() : Automobile(){
        override fun printMessage(){
            println("It's a Bus.")
        }
    }
    class Truck() : Automobile(){
        override fun printMessage(){
            println("It's a Truck.")
        }
    }
}
fun main() {
    val bus = Automobile.Bus()
    val truck = Automobile.Truck()
    bus.printMessage()
    truck.printMessage()
}

Sealed classes cannot be instantiated, as they themselves are the abstract class. And its constructors are used for creating the instance of the subclass.

The constructors of the sealed class can be one of these two types:

  • Protected: which is the default behavior
  • Private: which we can define explicitly when we want even stricter control over instantiation, enabling specific initialization procedures within the class.

The subclass must have one of these three modifiers: 

Sealed

It’s not mandatory that the sealed class is to be extended always. So, when the subclass that extends the sealed class is also a sealed class. And we don’t extend it further, we don’t get any errors. But yeah, we cannot instantiate it as well. Like in the code above mentioned, we have not extended the sealed subclass, still we got no errors. But if try to instantiate it, we would get error as follows: Sealed Modifier for the subclass of a sealed class in Kotlin

Open

When the sub-class of the sealed class is defined as open then it can be extended like any class. And then the further extended class will be the indirect child of the sealed class.

class MiniBus() : Bus(){
    override fun printMessage() {
        println("It's a Mini Bus.")
    }
}
Final

It is the default behaviour. If we want the class to be final, we skip the access modifier. When the subclass that extends the sealed class is a final class. Then, no class can extend that subclass. 

Default Modifier for the subclass of a sealed class in Kotlin

Java

In Java also, the class needs only the sealed modifier to be defined as sealed, whereas they can be preceded by the optional permits keyword followed by the permitted subclasses.

As in Kotlin, A class defined with sealed modifier cannot be instantiated. but in Java, they can be instantiated. See the example below:

sealed class Automobile permits Car, Bus, Truck {
    public void printMessage()
    {
        System.out.println("It's an Automobile.");
    }
}
sealed class Car extends Automobile {
    public void printMessage()
    {
        System.out.println("It's a Car.");
    }
}
non-sealed class Nano extends Car{
    public void printMessage()
    {
        System.out.println("It's a Nano Car.");
    }
}
non-sealed class Bus extends Automobile {
    public void printMessage()
    {
        System.out.println("It's a Bus.");
    }
}
final class Truck extends Automobile
{
    public void printMessage()
    {
        System.out.println("It's a Truck.");
    }
}
public class Main
{
    public static void main(String[] args)
    {
        Automobile car =  new Car();
        Automobile bus = new Bus();
        Automobile truck = new Truck();
        car.printMessage();
        truck.printMessage();
        bus.printMessage();
    }
}

The permitted subclass can have of one of these modifiers: 

Sealed

Unlike Kotlin, In Java, A sealed class must have a subclass. Whereas can skip the permits statement, and still extend the it. But if we permit some class to extend it, then it must extend, else we will get a compilation error. Like if we don’t extend the Automobile class in the Bicycle class, but we permit Bicycle class to extend the Automobile class. Then we will get the following compilation error:

Sealed Modifier for the subclass of a sealed class in Java
Non-sealed

In Kotlin, all open classes do not require extending the sealed class, but in Java, when the class is defined as non-sealed then it must have the parent class as sealed. Also, any class can extend the non-sealed class, as per its access modifier. 

Non-sealed Modifier for the subclass of a sealed class in Java
Final

When the subclass that extends the sealed class is a final class. Then, no class can extend that subclass. 

If you know more about new Java 17 features, check out this blog: Java 17 Unveiled: Exploring the Latest Features and Improvements

Picture of Nadra Ibrahim

Nadra Ibrahim

Software Consultant

Leave a Comment

Suggested Article

Discover more from NashTech Blog

Subscribe now to keep reading and get access to the full archive.

Continue reading