ホームページ  >  記事  >  Java  >  Java のシールド クラス

Java のシールド クラス

Susan Sarandon
Susan Sarandonオリジナル
2024-10-29 01:37:29655ブラウズ

Sealed Classes en Java

シールド クラス は、以前に JDK 15 で導入され、JDK 17 で正式に導入された機能です。シールド クラス は、次のことを行うことができないクラスです。 (クラス宣言で) 明示的に許可されていないクラスによって拡張される可能性があるため、サブクラスの数は制限されており、事前にわかっています。

これらは、継承階層をより正確に制御できるようにするとともに、考えられるすべてのサブクラスがわかっているドメインのモデリングを容易にし、コードのセキュリティと保守性を向上させることを目的としています。

シールド クラスと最終型のクラスの違いは、後者はどのクラスでも拡張できないのに対し、シールド クラスは限られた数だけ拡張できることです。クラスの数。

シールされたクラスの宣言

Shape クラスと Circle クラスの 2 つのクラスがあるとします。どちらも通常のクラスなので、Shape はどのクラスでも拡張できます。

public class Shape {
    // ...
}

public class Circle extends Shape {
    // ...
}

Shape クラスで Final キーワードを使用すると、どのクラスでも拡張できなくなります。

public final class Shape {
    // ...
}

public class Circle extends Shape { // Error
    // ...
}

ここで、Shape クラスを特定のクラス (Circle や Square など) によってのみ拡張したい場合は、それを sealed クラス として宣言できます。

public sealed class Shape permits Circle, Square {
    // ...
}

前の宣言を分析すると、sealed クラス であることを示すために、単語クラスの前に sealed を置く必要があることがわかります。次に、permits という単語が使用され、その後に現在のクラスを拡張できるクラスのリストが続きます。上の例では、Circle クラスと Square クラスのみが Shape クラスを拡張できます。

抽象型のクラス、つまりインスタンス化できないが、他のクラスによって拡張できるクラスを操作する場合にも、同じことが起こります。

public sealed abstract class Shape permits Circle, Square {
    // ...
}

この概念はインターフェースにも適用できます。

public sealed interface Shape permits Circle, Square {
    // ...
}

: 許可されたサブクラスは、sealed クラスと同じモジュールまたはパッケージ内に存在する必要があります。そうでない場合は、エラー メッセージが表示されます。

許可されるクラス

クラスが sealed と宣言され、許可されるクラスが指定されると、(extends Shape を配置することにより)許可されたクラスで Shape クラスを拡張すると、IDE は次のようなエラー メッセージを表示します。Modifier 'sealed' 、「未封印」または「最終」が予想されます、これはどういう意味ですか?

許可されるクラス (サブクラス) はそれぞれ、次のキーワードのいずれかを使用して宣言する必要があることを考慮する必要があります。

  • Final: クラスを拡張できないことを示します。
  • sealed: クラスが sealed クラス であり、サブクラスが許可されていることを示します。
  • non-sealed: クラスが sealed クラス ではなく、どのクラスでも拡張できることを示します。

上記を実践するために、Shape クラス、Circle、Square、Triangle クラスを使用して、上記に従って許可されたクラスをどのように宣言できるかを見てみましょう。

public class Shape {
    // ...
}

public class Circle extends Shape {
    // ...
}

サークルクラス - 最終回

Circle クラスを最終型にしたいため拡張できない場合は、次のように宣言する必要があります。

public final class Shape {
    // ...
}

public class Circle extends Shape { // Error
    // ...
}

これにより、Circle クラスが他のクラスによって拡張されなくなります。

スクエアクラス - 密閉型

Square クラスをシール型にし、それを拡張できるサブクラスを許可する場合は、次のように宣言する必要があります。

public sealed class Shape permits Circle, Square {
    // ...
}

この例では、許可された各クラス (SquareChild1 および SquareChild2) は、他のクラスによって拡張できないように、final 型で宣言されています。

public sealed abstract class Shape permits Circle, Square {
    // ...
}

これらのクラスをさらに多くのクラスで拡張できるようにしたい場合は、それらのクラスをシールドとして宣言するか、非シールの任意のクラスで拡張できるように宣言する必要があります。

トライアングルクラス - 非シール

Triangle クラスの場合、非シールとして宣言すると、許可されるクラスを指定することなく、このクラスを他のクラスで拡張できます。

public sealed interface Shape permits Circle, Square {
    // ...
}

たとえば、Triangle を拡張する TriangleChild クラスを作成した場合、エラー メッセージは表示されません。

public sealed class Shape permits Circle, Square, Triangle {
    // ...
}

この時点で、クラスを非シールとして宣言すると、シールされたクラスの目的を特定の方法で「破る」ことになることを考慮することが重要です。このクラスは他のクラスによって拡張でき、許可されるサブクラスの数は制限されません。

レコードをシールドクラスにすることはできますか?

一方、レコードはすでに最終型であり、他のクラスによって拡張できないため、sealed 型にすることはできません。ただし、できることは、sealed 型の インターフェース で許可されているように レコード を宣言することです (レコードはクラスを拡張できず、インターフェースのみを実装することを考慮してください)。たとえば、Rectangle というレコードと、sealed 型の Shape インターフェイスがある場合、Shape インターフェイスで許可されるように Rectangle を宣言できます。これにより、Rectangle は Shape インターフェイスと、このインターフェイスに含まれるすべてのメソッドを実装できるようになります。

public class Shape {
    // ...
}

public class Circle extends Shape {
    // ...
}

内部クラスについてはどうですか?

sealed として宣言されたクラスに内部クラス (ネストされたクラスまたは内部クラス) がある場合、これらのクラスはメイン クラスに属していると想定されるため、許可されると宣言する必要はありません。たとえば、Animal クラスが sealed として宣言されており、同時に内部クラスとして Dog と Cat がある場合、これらのクラスは許可として宣言する必要はありませんが、メイン クラスを拡張し、最終型である必要があります。 、密閉または非密閉。

public final class Shape {
    // ...
}

public class Circle extends Shape { // Error
    // ...
}

結論

シールド クラス は、クラス階層を許可されるサブクラスの有限数に制限する方法ですが、クラスが非シールドと宣言されると目的が多少失われることがわかりました。サブクラスをシールドとして使用すると、この階層をさらに拡張できます。

クラスをシールドとして宣言する場合、これはそのクラスを拡張できる人を指すだけであり、メインクラスのインスタンスの作成を制限したり、クラスのセマンティクスを変更したりするものではないことを考慮することが重要です。クラスの内部動作は変更されません。

以上がJava のシールド クラスの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。