はじめに
最近、Java SE 17 Programmer I (1Z0-825-JPN) 試験の勉強をしていて、そこで シールクラス(sealed class) という機能を知りました。シールクラスはJava 17から導入された機能で、特定のサブクラスにのみ継承を許可する便利な仕組みです。
本記事では、シールクラスの基本的な使い方と、その有用性について解説します。
対象読者
- Javaの継承の基本を理解している方
- シールクラスを知ったけど、具体的な使い道がわからない方
- finalクラスでは解決できない継承の制御に悩んでいる方
finalクラス では解決できない問題
Javaの継承は強力な機能ですが、意図しないクラスが継承できてしまうことがあります。例えば、動物 (Animal
) クラスを作って、そこから Dog
や Cat
を派生させたいとしましょう。しかし、間違って Human
まで Animal
を継承できてしまうかもしれません。
class Animal {}
class Dog extends Animal {}
class Cat extends Animal {}
class Human extends Animal {} // えっ!?
Human
は Animal
じゃないですよね?でも、今のままでは継承できてしまいます。Animal
の継承をDog
、 Cat
に限定するにはどうすれば良いでしょうか?
「Animal
をfinal
にすればいいのでは?」と思うかもしれません。しかし、それだとDog
やCat
も継承できなくなってしまいます。
final class Animal {} // これで継承禁止!
class Dog extends Animal {} // コンパイルエラー
class Cat extends Animal {} // コンパイルエラー
これでは本末転倒ですね。Human
の継承は防ぎたいけど、Dog
とCat
は許可したい…そんなときに シールクラス が役立ちます!
シールクラスで適切に継承を制限する
Java 17から導入されたシールクラス(sealed class) を使うと、
「特定のサブクラスにのみ継承を許可する」ことができます。
sealed class Animal permits Dog, Cat {}
final class Dog extends Animal {} // 継承OK
final class Cat extends Animal {} // 継承OK
class Human extends Animal {} // コンパイルエラー!
これでDog
とCat
だけがAnimal
を継承でき、Human
の継承を防ぐことができました!
シールクラスの制約
シールクラスを使う場合、サブクラスは以下のいずれかを選択する必要があります。
修飾子 | 説明 |
---|---|
final | これ以上継承できない(Dog や Cat ) |
sealed | さらに制限を加えた継承を許可する |
non-sealed | 制限を解除し、自由に継承できる |
例えば、Bird
というクラスを追加して、さらに細かく制限を加えることもできます。
sealed class Animal permits Dog, Cat, Bird {}
final class Dog extends Animal {} // これ以上継承不可
final class Cat extends Animal {} // これ以上継承不可
sealed class Bird extends Animal permits Sparrow {}
final class Sparrow extends Bird {} // これ以上継承不可
こうすることで、Bird
の派生クラスをSparrow
だけに限定できます。
まとめ
- シール(sealed)クラスは特定のサブクラスにのみ継承を許可する仕組みです
-
permits
で継承を許可するサブクラスを指定します - サブクラスは
final
、sealed
、non-sealed
のいずれかを選択する必要があります
Java 17以降を使っているなら、シールクラス をぜひ試してみてください!
参考
- 3 シール・クラス - Java