Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to restrict inheritance to a single subclass in Java

Tags:

java

Suppose there is class A which is parent class and class B that extends A.

Now I should not allow to extend class A to class C (class C extends A), or any other class.

How to do that?

like image 686
Saiprashanth Avatar asked Oct 31 '21 06:10

Saiprashanth


2 Answers

That's why Java 17 has sealed classes. This feature was added as a preview feature in Java 15.

Sealed classes and interfaces restrict which other classes or interfaces may extend or implement them.

In your case you can do the following:-

public sealed class A permits B {

}

public class B extends A{ //No error

}

public class C extends A{  //error because class C is not permitted 

}

The Goals of Sealed classes in java are :-

  • Allow the author of a class or interface to control which code is responsible for implementing it.

  • Provide a more declarative way than access modifiers to restrict the use of a superclass.

  • Support future directions in pattern matching by providing a foundation for the exhaustive analysis of patterns.


IF you want a class not extendable, then you can use final.

public final class A{ //Cannot be extended by other classes.
}

Helpful links:

https://docs.oracle.com/en/java/javase/15/language/sealed-classes-and-interfaces.html

http://openjdk.java.net/jeps/409

https://www.baeldung.com/java-sealed-classes-interfaces

What are sealed classes in Java 17

like image 81
JFan Avatar answered Sep 20 '22 06:09

JFan


If you are using an older version of Java, the natural solution is simply to make class A package-private. This prevents classes outside of the package from subclassing A directly.

If A itself does need to be exposed publicly, there is still a solution: declare another class PublicA which is public and final, where PublicA is a subclass of A with no additional or overridden members. Then classes in other packages can use PublicA instead of A, but they cannot subclass it.

The only other practical difference between PublicA and A is that the class B is a subclass of A but not a subclass of PublicA; so for example obj instanceof PublicA won't work to detect instances of B or other public subclasses of A. If an instanceof check like this might be required in other packages, then either a public interface can be exposed which A implements, or PublicA can expose a static method which returns arg instanceof A from inside the package, where it is allowed.

like image 38
kaya3 Avatar answered Sep 19 '22 06:09

kaya3