ProgrammingKotlin開発者、バックエンド開発者、Android開発者

Kotlinではsealedインターフェースはどのように実装されていますか?それは何のために使われ、どのように使用され、sealedクラスとは何が違うのですか?

Hintsage AIアシスタントで面接を突破

回答。

SealedインターフェースはKotlin(1.5以降)で比較的新しい機能で、特定のファイル内でインターフェースの実装のセットを制限することを目的としています。Kotlinでは元々sealedクラスが存在し、継承の階層に対して厳格なコントロールを提供し、完全な処理を容易にしました(例えば、when式での処理など)。

問題は、時々アーキテクチャには基本クラスではなく、同じ実装数の制限を持つインターフェースが必要とされることです。sealedインターフェースが登場する前は、コンパイラの制限に収まる唯一の方法はsealedクラスを使用することでしたが、これはドメインモデルに必ずしも上手く適合するわけではなく、特に複数継承やインターフェースへの振る舞いの分解が必要な場合には問題となります。

解決策:Sealedインターフェースは、すべての実装が同じファイル内で宣言される必要があるインターフェースを定義することを可能にします。これにより、コードの安全性が向上し、状態やイベントの階層を管理・ナビゲートすることが容易になります。

コードの例:

sealed interface NetworkState class Success(val data: String) : NetworkState class Error(val code: Int) : NetworkState object Loading : NetworkState

主な特徴:

  • sealedインターフェースは同じファイル内でのみ実装できます;
  • sealedインターフェース自体は状態を保持しませんが、それらの実装は状態を持つクラスやオブジェクトであることができます;
  • sealedインターフェースに対する完全なwhen式の処理。

トリッキーな質問。

sealedインターフェースは、宣言されているファイルの外で実装できますか?

いいえ。sealedクラスと同様に、sealedインターフェースはそれ自身の宣言があるファイル内でのみ実装できます。ファイルの外でこのインターフェースを実装しようとすると、コンパイルエラーが発生します。

sealedインターフェースはクラスから継承できますか?

いいえ、インターフェースは他のインターフェースからのみ継承できます。しかし、sealedインターフェースは他の(sealed)インターフェースから継承できます。

sealedインターフェースは多重継承をサポートしていますか?

はい、この同じファイル内のクラスは複数のsealedインターフェースを実装したり、sealedインターフェースとsealedクラスを同時に継承したりすることができます。

一般的なエラーとアンチパターン

  • sealedインターフェースをその宣言があるファイルの外で実装すること(コンパイラが許可しません)。
  • sealedインターフェースの誤用による厳密さの増加 — アーキテクチャの過度の複雑さにつながる可能性があります。
  • sealedインターフェースのインスタンスを直接作成しようとすること — これは不可能です:具体的な実装/オブジェクトのみです。

実生活の例

ネガティブケース

ネットワークイベント処理システムで、開発者は通常のインターフェースとsealedクラスを混在させて使用し、その結果「汚い」階層とコードの重複が生まれています。when式はelseブランチを含む必要があります。

利点:

  • 迅速に導入できるアーキテクチャ
  • 実装の柔軟性

欠点:

  • 階層の制御ができない
  • when式がコンパイラによって完全性をチェックされない

ポジティブケース

同じアプリケーションでsealedインターフェースNetworkEventに移行し、すべての実装を1つのファイルに配置します。これにより、NetworkEventに対するwhen式はすべてのケースの処理を必要とします。コードはより読みやすく、保守しやすく、安全になります。

利点:

  • 階層の完全な管理
  • コンパイラレベルでの状況の完全な処理のサポート

欠点:

  • すべての実装が1つのファイルに存在する必要があり、多くの選択肢がある場合にはファイルサイズが大きくなる。