SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

【最新Kotlinアップデート解説】バージョン1.1からの変更点総まとめ

Kotlin最新アップデートまとめ ──sealedやdata、プロパティに関するアップデート

【最新Kotlinアップデート解説】バージョン1.1からの変更点総まとめ 第3回

  • X ポスト
  • このエントリーをはてなブックマークに追加

 本連載は、Kotlinのバージョン1.1から2.0までのアップデート内容を、テーマごとにバージョン横断で紹介する連載です。今回と次回は、クラスやインターフェース、オブジェクトに関する変更点を紹介していきます。今回は、sealedやdata、および、プロパティに関する変更点を紹介します。

  • X ポスト
  • このエントリーをはてなブックマークに追加

sealedに関する変更点

 本連載は、Kotlinのバージョン1.1から2.0までのアップデート内容を、テーマごとにバージョン横断で紹介する連載です。今回と次回は、クラスやインターフェース、オブジェクトに関する変更点を紹介していきます。そのうち、最初に紹介するのは、sealedに関する変更点です。

sealedクラス定義

 sealed(シールド)クラスとは、その継承関係をコントロールできる仕組みです。例えば、リスト1のようなコードです。

[リスト1]sealedクラスの例
sealed class GinBaseCocktail {  // (1)
  fun getBaseName(): String {  // (2)
    return "ジン"
  }
  abstract fun getGinVolume(): Int  // (3)
}

 sealedクラスは、リスト1の(1)のように、クラス宣言にsealedキーワードを記述するだけで、その他は通常のクラスと同じように(2)のようなメソッド定義やプロパティ定義が可能です。

 ただし、sealedクラスとした時点で、抽象クラスとなります。そのため(3)のように抽象メソッドを定義でき、その際のクラス宣言にabstractは不要です。

sealedクラスの特徴

 sealedクラスが抽象クラスということは、そのままではインスタンスは生成できず、継承して利用されることを前提としています。そこまではabstractなクラスと同じですが、sealedクラス固有の特徴は「直接のサブクラスが、コンパイル時に全て把握されている」点です。

 例えば、リスト1のGinBaseCocktailを継承したサブクラスとして、WhiteLadyとMississippiMuleの2個が定義されているとします。すると、GinBaseCocktailのサブクラスはこの2個のみである、ということがコンパイル段階に確定し、保証されます。

 まさに、「sealed=封印された」の意味の如く、無制限にサブクラスが作成されるのではなく、サブクラスが封印されているという状態を実現する仕組みといえます。

 サブクラスが全て把握されているということは、例えば、リスト2のwhichCocktail()関数を定義できるようになります。

[リスト2]サブクラスに応じた分岐関数の例
fun whichCocktail(cocktail: GinBaseCocktail) {
  when(cocktail) {
    is WhiteLady -> {
      println("ホワイトレディです。")
    }
    is MississippiMule -> {
      println("ミシシッピミュールです。")
    }
  }
}

 この関数では、引数で受け取ったGinBaseCocktailインスタンスが、どのサブクラスかに応じて分岐処理が定義されています。大きな特徴は、when分岐内にelseブロックが不要である点です。

 これは、GinBaseCocktailがsealedクラスであり、そのサブクラスがWhiteLadyかMississippiMuleのどちらかであることが保証されているからこそ可能な仕組みです。

 ただし、サブクラスを作成する際に注意点があります。それは、そのサブクラスをopen、すなわち、継承可能なクラスとして作成してしまうと、そこから間接的なサブクラス(孫クラスやひ孫クラスなど)が作成可能となり、それらは把握されないサブクラスとして存在することになります。これではsealedの意味がなくなるので、注意してください。

sealedクラスのサブクラス定義の制約がなくなってきている

 また、さらなる制約として「sealedクラスとそのサブクラスは、同一パッケージ内に定義しなければならない」という条件があります。この点にも注意してください。

 これまでの例で言えば、sealedクラスであるGinBaseCocktail、そのサブクラスであるWhiteLadyとMississippiMuleは同一パッケージで宣言する必要があります。

 実は、Kotlinが正式リリースされた直後は、sealedクラスのサブクラスは、ネストクラスとして定義する必要がありました。それがバージョン1.1で制約が緩くなり、同一ファイルに定義する限りは、そのサブクラスをトップレベルクラスとして定義できるように変更されました。さらにバージョン1.5で、ファイルの分割が可能となりました。

 そのため、GinBaseCocktail、WhiteLady、MississippiMuleの3クラスは、それぞれ別ファイルに定義でき、1クラス1ファイルとして管理できるようになっています。ただし先述の通り、パッケージは同一である、という制約は残っているので注意してください。

sealedインターフェースの導入

 さらに同じく1.5で導入されたのが、sealedインターフェースです。これは、例えばリスト3のようなコードです。

[リスト3]sealedインターフェースの例
sealed interface Cocktail {
  fun getName(): String
}

 仕組みはsealedクラスと同じで、sealedキーワードを利用してインターフェースを宣言します。

 例えば、リスト1のGinBaseCocktailを、リスト4のように、このインターフェースを実装したクラスとしたとします。ただし、sealedクラス同様に、sealedインターフェースも同一パッケージで宣言する必要があります。

[リスト4]Cocktailインターフェースを実装したGinBaseCocktail
sealed class GinBaseCocktail : Cocktail {
  :
}

 そのサブクラスであるWhiteLadyは、リスト5のように、Cocktailインターフェースに定義されたgetName()とGinBaseCocktailクラスに定義された抽象メソッドであるgetGinVolume()の両方をオーバーライドする必要があります。MississippiMuleも同様です。

[リスト5]WhiteLadyクラスのコード例
class WhiteLady : GinBaseCocktail() {
  override fun getName(): String {
    return "ホワイトレディ"
  }
  override fun getGinVolume(): Int {
    return 30
  }
}

 さらに、図1のように、Cocktailインターフェースを頂点とする継承構造が、コンパイル段階で確定していることが保証されます。

図1:sealedの仕組みにより確定されている継承構造
図1:sealedの仕組みにより確定されている継承構造

次のページ
dataに関する変更点

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
【最新Kotlinアップデート解説】バージョン1.1からの変更点総まとめ連載記事一覧

もっと読む

この記事の著者

WINGSプロジェクト 齊藤 新三(サイトウ シンゾウ)

WINGSプロジェクトについて>有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティ(代表 山田祥寛)。主にWeb開発分野の書籍/記事執筆、翻訳、講演等を幅広く手がける。2018年11月時点での登録メンバは55名で、現在も執筆メンバを募集中。興味のある方は、どしどし応募頂きたい。著書記事多数。 RSS X: @WingsPro_info(公式)、@WingsPro_info/wings(メンバーリスト) Facebook <個人紹介>WINGSプロジェクト所属のテクニカルライター。Web系製作会社のシステム部門、SI会社を経てフリーランスとして独立。屋号はSarva(サルヴァ)。HAL大阪の非常勤講師を兼務。

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

山田 祥寛(ヤマダ ヨシヒロ)

静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for Visual Studio and Development Technologies。執筆コミュニティ「WINGSプロジェクト」代表。主な著書に「独習シリーズ(Java・C#・Python・PHP・Ruby・JSP&サーブレットなど)」「速習シリーズ(ASP.NET Core・Vue.js・React・TypeScript・ECMAScript、Laravelなど)」「改訂3版JavaScript本格入門」「これからはじめるReact実践入門」「はじめてのAndroidアプリ開発 Kotlin編 」他、著書多数

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/21732 2025/06/24 11:00

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング