Sealed classes became a standard feature in Java 17. In Java 15 and 16 it was a preview feature. In this tutorial we'll see why do you need Sealed classes or interface in Java and how to use them
Why sealed classes and interfaces
Java is an object-oriented language and does support the object-oriented principal Inheritance. But if you notice Inheritance in Java doesn't provide much control over which classes should be permitted to extend a parent class. In fact, in Java, it is all or none kind of scenario, if you have a normal class then any class can extend it, or in case of a final class it can't be extended by any class.
That's what sealed class provides you; a fine grained control over inheritance. By sealing a class, you can specify which classes are permitted to extend it and prevent any other arbitrary class from doing so.
Same way with sealed interfaces you can specify which classes are permitted to implement it and which interfaces are permitted to extend it.
How to create a sealed class
For creating a sealed class in Java, you have to use the following steps-
- To create a sealed class, add the
sealed
modifier to its declaration. - Add the
permits
clause to specify the classes that may extend the sealed class. - The extending class must use one of the following modifiers to describe how it continues the sealing initiated by
its superclass-
- final: Cannot be extended further
- sealed: Can only be extended by its permitted subclasses
- non-sealed: Can be extended by any other class
Sealed class Java example
For example, the following declaration of Account specifies three permitted subclasses SavingAccount, CurrentAccount and SalaryAccount.
public sealed class Account permits SavingAccount, CurrentAccount, SalaryAccount{ private double balance; public void withdraw(double amount) { balance = balance - amount; } public void deposit(double amount) { balance += amount; } }
Define the following three permitted subclasses SavingAccount, CurrentAccount and SalaryAccount in the same module or in the same package as the sealed class Account.
SavingAccount.java
public sealed class SavingAccount extends Account permits PrivilegedSavingAccount{ private double rateOfInterest = 4; }
CurrentAccount.java
public final class CurrentAccount extends Account{ private double rateOfInterest = 0.5; }
SalaryAccount.java
public non-sealed class SalaryAccount extends Account{ private double rateOfInterest = 3; }
SavingAccount has a further subclass, PrivilegedSavingAccount which should also follow the same procedure of permitting 3 types of sub-classes for a sealed class.
PrivilegedSavingAccount.java
public final class PrivilegedSavingAccount extends SavingAccount{ private int priority = 1; }
If any class which is not in the list of permitted classes try to extend the Account class gives the following error.
public sealed class Test extends Account{ }
Sealed class or interface lacks the permits clause and no class or interface from the same compilation unit declares Test as its direct superclass or superinterface
Constraint on sealed and permitted sub-classes
- All the permitted subclasses must be accessible by the sealed class at compile time. For example, to compile Account.java, the compiler must be able to access all of the permitted classes of Account: SavingAccount.java, CurrentAccount.java and SalaryAccount.java. Out of these classes SavingAccount is a sealed class so compiler also needs access to PrivilegedSavingAccount.java.
- Permitted subclasses must directly extend the sealed class.
- Permitted subclasses must be in the same module as the sealed class or in the same package.
- You can define permitted subclasses in the same file as the sealed class. If you do so, then you can omit
the permits clause.
public sealed class Account { private double balance; public void withdraw(double amount) { balance = balance - amount; } public void deposit(double amount) { balance += amount; } } final class CurrentAccount extends Account{ private double rateOfInterest = 0.5; } non-sealed class SalaryAccount extends Account{ private double rateOfInterest = 3; } sealed class SavingAccount extends Account permits PrivilegedSavingAccount{ private double rateOfInterest = 4; } final class PrivilegedSavingAccount extends SavingAccount{ private int priority = 1; }
Defining Sealed interface
A sealed interface lets you specify the interfaces that can extend it and the classes that can implement it. It follows rules similar to sealed classes.
You can't declare an interface using the modifier final so you can specify an inheriting interface as either sealed or non-sealed but not final.
sealed public interface MyInterface permits MyClass, AnotherInterface{ }
public final class MyClass implements MyInterface{ }
public non-sealed interface AnotherInterface extends MyInterface{ }
That's all for this topic Java Sealed Classes and Interfaces. If you have any doubt or any suggestions to make please drop a comment. Thanks!
>>>Return to Java Advanced Tutorial Page
Related Topics
You may also like-
No comments:
Post a Comment