Kotlinのシールドクラス(Sealed Class)を活用したエラーハンドリング【Kotlin入門⑰】

シールドクラス(Sealed Class)とは?

シールドクラスの概要

シールドクラス(Sealed Class)とは、Kotlinにおいてクラスの継承を制限し、特定のサブクラスのみを許可するクラスのことです。これは、分岐処理やエラーハンドリングなどの用途でよく使用されます。

シールドクラスの特徴

  • 同じファイル内でのみ継承が可能
  • クラスの種類を制限できるため、安全な型チェックが可能
  • when 式と組み合わせることで、明示的なエラーハンドリングが可能
sealed class Result {
    class Success(val data: String) : Result()
    class Error(val message: String) : Result()
}

シールドクラスを使ったエラーハンドリング

when 式との組み合わせ

シールドクラスを使用すると、when 式による型チェックが安全に行えます。

fun handleResult(result: Result) {
    when (result) {
        is Result.Success -> println("成功: ${result.data}")
        is Result.Error -> println("エラー: ${result.message}")
    }
}

Kotlinでは、シールドクラスを when で評価する際にすべての可能性を網羅していれば、else 分岐が不要になります。これにより、コードの安全性と可読性が向上します。

実践例:APIレスポンスのエラーハンドリング

シールドクラスを使うと、APIのレスポンスを分岐しやすくなります。

sealed class ApiResponse<out T> {
    data class Success<T>(val data: T) : ApiResponse<T>()
    data class Error(val message: String) : ApiResponse<Nothing>()
    object Loading : ApiResponse<Nothing>()
}

fun fetchData(): ApiResponse<String> {
    return try {
        val data = "APIからのデータ" // 実際はネットワーク処理
        ApiResponse.Success(data)
    } catch (e: Exception) {
        ApiResponse.Error("データ取得に失敗: ${e.message}")
    }
}
fun main() {
    val response = fetchData()
    when (response) {
        is ApiResponse.Success -> println("データ取得成功: ${response.data}")
        is ApiResponse.Error -> println("エラー: ${response.message}")
        ApiResponse.Loading -> println("データ取得中...")
    }
}

シールドインターフェース(Sealed Interface)

Kotlin 1.5 以降では、シールドインターフェース(sealed interface)もサポートされています。これにより、より柔軟な設計が可能になります。

sealed interface NetworkResult

class Success(val data: String) : NetworkResult
class Failure(val error: String) : NetworkResult

fun handleNetworkResult(result: NetworkResult) {
    when (result) {
        is Success -> println("成功: ${result.data}")
        is Failure -> println("エラー: ${result.error}")
    }
}

シールドクラス vs. Enumクラス

比較項目シールドクラスEnumクラス
継承可能性可能(複数の型を持てる)不可能(固定値のみ)
データの保持コンストラクタを持てる固定値のみ保持
when との相性else 不要else 不要
拡張性高い(サブクラス追加可能)低い(列挙値のみ)

シールドクラスは、Enumクラスよりも柔軟であり、複雑なデータ構造やエラーハンドリングに適しています。

まとめ

本記事では、Kotlinのシールドクラス(Sealed Class)を活用したエラーハンドリングについて解説しました。

  • シールドクラスは、特定のサブクラスのみ継承可能なクラス
  • when 式と組み合わせることで、安全な型チェックが可能
  • APIレスポンスやエラーハンドリングに最適
  • シールドインターフェースも利用可能
  • Enumクラスと比較すると、より柔軟な設計が可能

Kotlinのシールドクラスを活用することで、より安全で可読性の高いコードを実装できるようになります。ぜひ、実践に取り入れてみてください!