簡體   English   中英

如何在 Java 中將繼承限制為單個子類

[英]How to restrict inheritance to a single subclass in Java

假設有A類是父類, B類擴展了A

現在我不應該允許將A類擴展到C class C extends Aclass 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

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

什么是 Java 17 中的密封類

如果您使用的是舊版本的 Java,自然的解決方案就是將A類包設為私有。 這可以防止包外的類直接子類化A

如果A本身確實需要公開,仍然有一個解決方案:聲明另一個公共和最終類PublicA ,其中PublicAA的子類,沒有額外或覆蓋的成員。 然后其他包中的類可以使用PublicA而不是A ,但它們不能子類化它。

PublicAA之間唯一的另一個實際區別是類BA的子類,但不是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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM