Reputation: 481
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?
Upvotes: 14
Views: 2308
Reputation: 1051
From Java 15 onward such use-case can be implemented by using sealed modifier and permits clause
The restriction of a class or interface to become a parent for a specific class or interface. Following are two use case one for class and another for interface.
1. Using Class: Suppose we have an class ClazzA, we want to restrict this class to extend only by class ClazzB. That is no any other class can extends ClazzA except ClazzB.
public abstract sealed class ClazzA permits ClazzB {
final String str;
public ClazzA(String str) {
this.str = str;
}
public void method() {
// TODO
}
}
2. Using Interface: Suppose we have an interface InterfaceA, we want to restrict this interface to extend only by interface InterfaceB. That is no any other interface can extends except InterfaceB
public sealed interface InterfaceA permits InterfaceB {
int method1();
default int defaultMethod() {
return 0;
}
}
Upvotes: -1
Reputation: 744
That's why Java 17 has sealed classes. This feature was added as a preview feature in Java 15.
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
}
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.
}
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
Upvotes: 26
Reputation: 51034
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.
Upvotes: 5