Kotlinの初期バージョンでは、型階層を制限するためにシールドクラスが使用されており、開発者が同じファイル内でのみ継承者の宣言を制限することによって許可されるサブタイプを明示的に制御できました。しかし、インターフェースを使用して類似の階層を説明する必要がある場合には、これは不十分でした。この問題を解決するために、Kotlin 1.5からインターフェース用のsealed修飾子が導入されました。
通常のインターフェースはプロジェクトの任意の場所で実装できるため、型階層の絶対的な閉鎖性を確保し、包括的な型チェック(exhaustive when)を使用することがしばしば妨げられます。これにより、ランタイムエラーやすべてのケースを静的にチェックできないことにつながる可能性があります。
シールドインターフェースを使用すると、実装クラスのリストを同じファイル内に制限できるため、型システムの予測可能性を向上させ、パターンマッチングの安全性を高めることができます。
sealed interface NetworkResult class Success(val data: String): NetworkResult class Failure(val error: Throwable): NetworkResult fun handle(result: NetworkResult) = when(result) { is Success -> println("Data: ${result.data}") is Failure -> println("Error: ${result.error}") // すべてのケースが考慮されているので、'else'は不要 }
主な特徴:
シールドインターフェースを別のファイルに追加したり、元のファイルの外で実装したりできますか?
いいえ。シールドインターフェースを直接実装するすべての型は同じファイルで宣言されている必要があります。そうしないと、コンパイラーがエラーを出します。
シールドインターフェースは宣言ファイルの外にサブインターフェースを持つことができますか?
いいえ。サブインターフェースも同じファイル内に存在する必要があります。すべての階層はファイル内で閉じられています。
シールドインターフェースはランタイムパフォーマンスに影響を与えますか?
直接的にはそうではありませんが、コンパイル時に安全な型チェックを使用できるため、ランタイムエラーの可能性を減少させ、コードを簡素化し、テスト速度を間接的に向上させる可能性があります。
開発者が1つのファイルでシールドインターフェースNetworkActionを宣言するが、実装が異なるクラスやファイルに分散している。問題が遅れて発生する:コンパイラーがルール違反を警告し、構造を修正するのが難しい、特に大規模プロジェクトで特に厄介。
利点:
欠点:
シールドインターフェースOrderResultとクラスSuccess/Failureが1つのファイル内で宣言される。whenチェックは常に包括的で、すべてのブランチが考慮されている。
利点:
欠点: