[英]How to restrict inheritance to a single subclass in Java
假設有A
類是父類, B
類擴展了A
。
現在我不應該允許將A
類擴展到C
class C extends A
( class C extends A
)或任何其他類。
怎么做?
這就是 java-17 具有密封類的原因。 此功能是在 java-15 中作為預覽功能添加的。
在您的情況下,您可以執行以下操作:-
public sealed class A permits B {
}
所以它只能由B類而不是C類擴展。
有用的網址:
https://docs.oracle.com/en/java/javase/15/language/sealed-classes-and-interfaces.html
http://openjdk.java.net/jeps/409
如果您使用的是舊版本的 Java,自然的解決方案就是將A
類包設為私有。 這可以防止包外的類直接子類化A
如果A
本身確實需要公開,仍然有一個解決方案:聲明另一個公共和最終類PublicA
,其中PublicA
是A
的子類,沒有額外或覆蓋的成員。 然后其他包中的類可以使用PublicA
而不是A
,但它們不能子類化它。
PublicA
和A
之間唯一的另一個實際區別是類B
是A
的子類,但不是PublicA
的子類; 因此,例如obj instanceof PublicA
將無法檢測B
實例或A
其他公共子類。 如果其他包中可能需要這樣的instanceof
檢查,則可以公開A
實現的公共接口,或者PublicA
可以公開靜態方法,該方法從包內部返回arg instanceof A
,這是允許的。
可以使用 Java 15 中首次引入的密封類( JEP 360:密封類(預覽版))來回答您的問題。由於使用類已經回答了這個問題,因此我還想提供一個帶有密封接口的示例。
public sealed interface Animal permits Cat {
String makeSound();
}
public final class Cat implements Animal {
@Override
public String makeSound() {
return "miau";
}
}
如果您只想允許來自密封接口的一個實現,那么您必須確保使用該接口的類設置為final 。 否則類可以從Cat
擴展。
從 Java 15 開始,這種用例可以通過使用Sealed 修飾符和permit 子句來實現
限制類或接口成為特定類或接口的父類。 以下是兩個用例,一個用於class ,另一個用於interface 。
1.使用類:假設我們有一個類ClazzA,我們想限制這個類只能由類ClazzB擴展。 除了 ClazzB 之外,沒有任何其他類可以擴展 ClazzA。
public abstract sealed class ClazzA permits ClazzB {
final String str;
public ClazzA(String str) {
this.str = str;
}
public void method() {
// TODO
}
}
2.使用接口:假設我們有一個接口InterfaceA,我們想限制這個接口只能由接口InterfaceB擴展。 除了InterfaceB,沒有任何其他接口可以擴展
public sealed interface InterfaceA permits InterfaceB {
int method1();
default int defaultMethod() {
return 0;
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.