DEV Community

Cover image for Sealed class rules in Java
MyExamCloud
MyExamCloud

Posted on

Sealed class rules in Java

Sealed classes are a new feature introduced in Java versions 15 and above, designed to provide more control and flexibility over class inheritance within a module. A sealed class imposes certain constraints on its subclasses, allowing for a restricted and organized structure of class hierarchy.

To begin, a sealed class and its subclasses must belong to the same module, or if declared in an unnamed module, the same package. This ensures that all classes within a sealed class's hierarchy are accessible and manageable within a specific environment.

Furthermore, every permitted subclass must directly extend the sealed class. This ensures a clear and concise hierarchy, without any subclasses branching out in an unexpected way.

Next, every permitted subclass must choose a modifier to describe how it continues the sealing initiated by its superclass. There are three options for these modifiers:

1) Final: This modifier makes the subclass the final level in the class hierarchy, prohibiting any further extension.

2) Sealed: This modifier allows the subclass to be extended further, but in a restricted fashion. All subclasses of a sealed subclass must be explicitly permitted by the sealed superclass.

3) Non-sealed: This modifier reverts the subclass's part of the hierarchy to an open state, allowing for unknown subclasses to extend it.

As an example, consider a Shape class that is declared as sealed, with two permitted subclasses - Circle and Square. In this case, Circle can be declared as final, while Square can be declared as non-sealed, allowing for unknown subclasses to further extend it.

It is important to note that a class can only have one modifier out of final, sealed, and non-sealed. It is not possible for a class to be sealed and final at the same time, as they serve opposite purposes.

Additionally, abstract classes can also be declared as sealed or non-sealed, and may have abstract members. Sealed classes may permit abstract subclasses as long as they are also sealed or non-sealed.

Lastly, a permitted subclass's accessibility does not have to match that of the sealed class. Subclasses can be less accessible, as long as they are still accessible to the sealed class. This may result in some users being unable to exhaustively switch over subclasses without a default clause in the future release when pattern matching is supported by switches.

To better understand the concept of sealed classes, let's take a look at some coding examples.

In the code snippet below, a sealed class Currency is defined.

sealed class Currency permits Dinar {
    //:sealed Check out the non-sealed class inheritance for legal recommendations
}
Enter fullscreen mode Exit fullscreen mode

In order for a legal subsclass to be created, the class must be declared in the same module and be directly extend the Currency class. A sealed class cannot prevent its permitted subclasses from extending further in a restricted fashion or being open for extension by unknown subclasses. Hence Dinar must be in the same module.

Taking the code snippet further, the non-sealed class Dinar extends the sealed class Currency. The non-sealed class allows for further subclasses to be created and extended.

public non-sealed class Dinar extends Currency {
    // This class can be extended by any unknown subclass
}
Enter fullscreen mode Exit fullscreen mode

Alternatively, if we want to restrict the subclasses that can extend Dinar, we can declare the class as sealed and specify which subclasses are permitted through the permits clause.

sealed class Dinar extends Currency permits JordanianDinar, KuwaitiDinar {
    // Only subclasses JordanianDinar and KuwaitiDinar are permitted 
}
Enter fullscreen mode Exit fullscreen mode

The subclasses JordanianDinar and KuwaitiDinar must be declared in the same module as Dinar and must directly extend the sealed class Dinar. They can either be sealed, non-sealed, or even final, depending on the desired level of restriction.

Using sealed classes, we can create a hierarchy of related classes and have more control over which subclasses can be created and extended, providing better encapsulation and modularity in our code. It also helps enhance type safety as the compiler can warn us if we try to create an illegal subclass.

In conclusion, sealed classes offer a more organized and structured approach to class inheritance, allowing for more control and flexibility within a module. By imposing restrictions on subclasses and providing options for further extension, sealed classes provide a more deliberate and intentional class hierarchy.

Top comments (0)