Sealed 型の宣言
型を拡張できる対象を制限します。
「Sealed 型の宣言」はCoddyKit上の無料Java Academyレッスンです。 これはレッスン1/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはJava Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Java Academyコースには全4レッスンが含まれています。
sealed型とは
sealedクラスまたはインターフェースは、それを継承または実装できる他の型を制限します。これにより、コンパイラーが把握できる閉じた選択肢の集合をモデル化できます。
解決する問題
通常のpublicクラスは、誰でもどこからでもサブクラス化できます。しかし、予期しない追加を許さず、ちょうど3種類の形状や2種類の支払い方法だけを扱いたい場合があります。sealedを使うと、その意図を明示して強制できます。
sealedキーワード
型にsealedを付け、permitsで許可するサブタイプを列挙します。許可された各サブタイプは、それぞれ独自の継承修飾子を宣言する必要があります。
public class Main {
sealed interface Shape permits Circle, Square {}
record Circle(double radius) implements Shape {}
record Square(double side) implements Shape {}
public static void main(String[] args) {
Shape s = new Circle(2.0);
System.out.println(s);
}
}サブタイプの修飾子
許可された各サブタイプは、final(これ以上のサブクラス化を禁止)、sealed(制限を継続)、non-sealed(自由な拡張を再び許可)のいずれかでなければなりません。レコードは暗黙的にfinalです。
finalサブクラス
サブクラスにfinalを付けると、その分岐で継承階層を閉じられます。
public class Main {
sealed interface Animal permits Dog, Cat {}
static final class Dog implements Animal {
public String toString() { return "Dog"; }
}
static final class Cat implements Animal {
public String toString() { return "Cat"; }
}
public static void main(String[] args) {
Animal a = new Dog();
System.out.println(a);
}
}non-sealedサブクラス
non-sealedサブタイプは意図的に拡張を再び許可し、未知のクラスがそのサブタイプをさらに継承できるようにします。1つの分岐だけを開いたままにする必要がある場合に、慎重に使ってください。
public class Main {
sealed interface Plugin permits CorePlugin, ExternalPlugin {}
static final class CorePlugin implements Plugin {}
static non-sealed class ExternalPlugin implements Plugin {}
static class ThirdParty extends ExternalPlugin {}
public static void main(String[] args) {
Plugin p = new ThirdParty();
System.out.println(p.getClass().getSimpleName());
}
}sealedクラスも使える
sealedにできるのはインターフェースだけではありません。abstractなsealed classも同じように機能し、共有する状態や振る舞いを保持できます。
public class Main {
sealed static abstract class Expr permits Num, Add {}
static final class Num extends Expr {
final int value;
Num(int value) { this.value = value; }
}
static final class Add extends Expr {
final Expr left, right;
Add(Expr left, Expr right) { this.left = left; this.right = right; }
}
public static void main(String[] args) {
Expr e = new Add(new Num(1), new Num(2));
System.out.println(e.getClass().getSimpleName());
}
}同じモジュールまたはパッケージ
許可されたサブタイプは、sealed型と同じモジュールに配置する必要があります。コードがモジュール化されていない場合は、同じパッケージに配置します。これにより、閉じた集合をまとめて検証できます。
コンパイラーによる強制
クラスがpermitsに列挙されずにsealed型を継承しようとすると、コードはコンパイルできません。閉じた集合であることがコンパイル時に保証されます。
重要な理由
コンパイラーはすべてのサブタイプを把握しているため、sealed型に対するswitchがすべてのケースを処理しているか検証できます。これは、後のコースで扱う網羅的なパターンマッチングの基盤になります。
完全な継承階層
ここでは、値のモデルとして使う小さな閉じた継承階層を示します。
public class Main {
sealed interface Json permits JsonNull, JsonNumber, JsonString {}
record JsonNull() implements Json {}
record JsonNumber(double value) implements Json {}
record JsonString(String value) implements Json {}
public static void main(String[] args) {
Json[] values = { new JsonNull(), new JsonNumber(3.5), new JsonString("hi") };
for (Json j : values) {
System.out.println(j);
}
}
}理解度チェック
sealed宣言についての理解度を確認しましょう。
まとめ
sealed型の宣言方法を学びました。
sealedは、型を継承または実装できる対象を制限します。permits句は、許可されるサブタイプを列挙します。- 各サブタイプは
final、sealed、non-sealedのいずれかでなければなりません。 - サブタイプは同じモジュールまたはパッケージに配置し、コンパイラーによって検証されます。
よくある質問
「Sealed 型の宣言」レッスンは無料ですか?
はい。「Sealed 型の宣言」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Java Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Java Academyコースには全4レッスンが含まれています。
「Sealed 型の宣言」で何を学びますか?
型を拡張できる対象を制限します。 ブラウザで直接実行するハンズオンコードでJava Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
Java Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのJava Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン1/4です。
「Sealed 型の宣言」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このJava Academyレッスンでコードを書いて実行できますか?
はい。すべてのJava Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。