Thursday, February 11, 2021

Sealed Classes

In the next set of posts, lets see some of the features of Java language. 

We will start with sealed classes. This is introduced as a preview feature in Java15. 

So what is a sealed class? 

In java language we can have a final class or a non-final class (class not declared as final). A final class cannot be sub-classed. Non-final class can be extended by any class as long as the base class is visible to it. What if we want to define the entire class hierarchy and not leave it open for any class to extend our class hierarchy in the future?

Lets take a simple example. Lets say we run a pet shop and exclusively deal only with cats & dogs. We want to model this and define a class hierarchy for our case. We will have a base Pet interface, Cat & Dog class both implement the Pet interface. While we want to allow any no. of sub classes for Cat, we want to restrict Dog class to be extended only by the two types of dog we deal with. The hierarchy we want is as shown below




Now we don't want any other class or interface to implement or extend from Pet Interface. Similarly we don't want any other classes other than GermanShepard & LabradorRetriever to extend from Dog class. How can we control this? Sealed classes helps here.

Lets understand some keywords first

sealed: A class can be declared as sealed. It means that this class can be extended only by the set of classes mentioned in the permits clause of its definition

permits: Allows to specify a comma separated set of classes that are permitted to extend from the sealed class

non-sealed: When a class extends from a sealed class, it has to be declared as one of 

  1. final - it cannot be extended any further
  2. sealed - it itself is also sealed, with the set of classes that can extend from it declared in its own permits clause
  3. non-sealed - Specifies that the class hierarchy at this point is no longer sealed and any no. of classes can extend from it

Sample code that implements the type hierarchy shown in the above diagram is given below

public sealed interface Pet permits Cat, Dog {

}

public abstract non-sealed class Cat implements Pet {

}

public abstract sealed class Dog implements Pet permits GermanShepard, LabradorRetriever {

}

public final class GermanShepard extends Dog {

}

public final class LabradorRetriever extends Dog {

}

Here Pet is the interface which allows only Cat & Dog types to implement or extend it.

Cat & Dog are abstract classes. While Cat is non-sealed allowing any class to extend from it, Dog is sealed and allows only GermanShepard & LabradorRetriever classes to extend from it.

GermanShepard & LabradorRetriever are final classes and would prevent any other class to extend from it.

Sealed classes helps impose tight control over type hierarchy that we want to have. Though this feature is commonly referred to as sealed classes, it applies to interfaces as well.

Note: This is a preview feature in Java 15. To compile the above code, use the command with --enable-preview flag as shown below

javac --enable-preview --release 15 *.java

And to run code that uses preview features, run the application with --enable-preview option like

java --enable-preview Main

If you are using Eclipse, enable preview feature by selecting this option


We will get into detailed usage of sealed classes next

Sample code used in this post can be downloaded from https://github.com/ashokkumarta/awesomely-java/tree/main/2021/02/Language-Features/Sealed-classes/Sealed-classes

No comments:

Post a Comment