In Java, to prevent the inheritance of a certain class, we will use the final keyword to declare that class. Examples are as follows:
1 2 3 4 5 6 7 8 9 10 11 |
package com.huongdanjava.javaexample; public final class JavaExample { public static void main(String[] args) { } class Test extends JavaExample { } } |
Class Test will not be able to inherit JavaExample class because this JavaExample class is declared with final:
A need in some cases is that we need to specify which classes are allowed to inherit from the parent class and which are not. We do not want to prevent inheritance from all classes, because there are cases where we want some classes in our library to inherit from that parent class, not allowing inheritance from other classes.
For example:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
package com.huongdanjava.javaexample; public class JavaExample { public static void main(String[] args) { } class Test1 extends JavaExample { } class Test2 extends JavaExample { } } |
In this example, I want the Test1 and Test2 classes to inherit from the JavaExample class, but I don’t want other classes to inherit from this JavaExample class. I cannot declare this JavaExample class with final keyword. And that’s why sealed class was introduced in Java.
Sealed class will help us restrict the inheritance of a certain class. We can control which classes can inherit from the parent class.
To implement the sealed class, we will use the sealed and permits keyword pair to declare the class that we want to seal.
In the above example, I would declare the following:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
package com.huongdanjava.javaexample; public sealed class JavaExample permits JavaExample.Test1, JavaExample.Test2 { public static void main(String[] args) { } final class Test1 extends JavaExample { } final class Test2 extends JavaExample { } } |
The sealed keyword is declared after the access modifier of the class and the permits keyword will be declared along with a list of subclasses that we allow them to inherit from this class. You also notice that we also need to declare the subclasses as final so that no class can inherit from these subclasses anymore.
If you have a need to allow the Test1 class to inherit from other classes, then declare this Test1 class with the non-sealed keyword. Then class Test1 can be inherited without any limitation, for example:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
package com.huongdanjava.javaexample; public sealed class JavaExample permits JavaExample.Test1, JavaExample.Test2 { public static void main(String[] args) { } non-sealed class Test1 extends JavaExample { } class Test3 extends Test1 { } final class Test2 extends JavaExample { } } |
We can also continue to restrict inheritance for the Test2 class like the JavaExample class by declaring the sealed and permits keywords:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
package com.huongdanjava.javaexample; public sealed class JavaExample permits JavaExample.Test1, JavaExample.Test2 { public static void main(String[] args) { } non-sealed class Test1 extends JavaExample { } class Test3 extends Test1 { } sealed class Test2 extends JavaExample permits Test4 { } final class Test4 extends Test2 { } } |
There are a few points you need to know more about:
– If the child class is in the same class file as the parent class, you can omit the permits keyword. For example, in the example above, I can leave out the Test4 permits declaration in the Test2 class definition without any errors:
– Local classes (classes defined inside the method) can inherit from non-sealed classes:
but cannot inherit from sealed class.