サイトロゴ

Enjoy Creating
Web & Mobile Apps

MENU BOX
WEB
MOBILE
OPEN

ホーム

 > 

 > 

【Kotlin】拡張関数と拡張プロパティの基本

【Kotlin】拡張関数と拡張プロパティの基本

この記事にはプロモーションが含まれています。

Kotlinには、拡張関数・拡張プロパティと呼ばれる、class のメソッドやプロパティを後から独自に拡張できる機能が備わっています。

この記事では、拡張関数・拡張プロパティの基本と、便利な使用例をいくつかご紹介します!

この記事を読むことで分かること
  • ・拡張プロパティの基本
  • ・拡張関数の基本
  • ・具体的な活用例

– 目次 –

拡張プロパティの基本

拡張関数・拡張プロパティの基本を理解するために、極めてシンプルな class を定義しておきたいと思います。

下のコードは、自分のプロフィールを管理する class を想定していますが、ご覧の通り name プロパティしか持っていません。

Kotlin

class MyProfile {
    val name = "Tom"
}

プロフィール情報が名前だけでは物足りないので、年齢を表す age プロパティを追加したくなったとしましょう。

この時、定義された class を自由に編集できる状況であれば、下のように class 内に age プロパティを追加すれば良いでしょう。

Kotlin

class MyProfile {
    val name = "Tom"
    val age = 32
}

しかし、外部のライブラリで定義された class など、class を自由に編集できない場合も少なくありません。

そのような場合、class の内部にプロパティやメソッドを直接定義することはできませんが、拡張関数・拡張プロパティという形であれば、独自にプロパティやメソッドを追加することが可能です。

もし、MyProfile class を直接編集することができないシチュエーションならば、次のように拡張プロパティを利用することで、class にプロパティを追加することができます。

Kotlin

class MyProfile {
    val name = "Tom"
}

val MyProfile.age
get () = 32

fun main() {
    val myProfile = MyProfile()
    println(myProfile.age) // Outputs: 32
}

通常のプロパティにアクセスするのと同じように、拡張プロパティも【 .(ドット)】でアクセスすることができます。

なお、拡張プロパティはカスタムゲッターを用いて定義する必要があり、下のように直接的に値を代入するコードはエラーになります。

Kotlin

class MyProfile {
    val name = "Tom"
}
val MyProfile.age = 32 // This code will cause an error

これは拡張プロパティがバッキングフィールドを持てないためで、拡張プロパティは実際にデータを内部に持つのではなく、ゲッターによって毎回計算される仕組みが関係しています。(そのため、拡張プロパティにカスタムセッターを設定することはできません。)

いくら拡張プロパティを利用することで後から class を拡張できるとは言え、ある程度制限がかかってしまうことは覚えておくと良いと思います。

    POINT!
  1. ・カスタムプロパティを利用することで、既存のclassに後からプロパティを追加できる!
  2. ・ただし、カスタムプロパティは内部にデータを保持するものではない!
  3. ・そのため、カスタムゲッターによって設定される必要があり、カスタムセッターは設定できない!

拡張関数の基本

前のステップでは拡張プロパティの例を示したので、このステップでは拡張関数の例を紹介します。

引き続き、MyProfile class を例にしてみましょう。

下のコードは、拡張関数を利用して、name プロパティに格納された文字列(名前)を出力するメソッド printName()MyProfile に追加した例です。

Kotlin

class MyProfile {
    val name = "Tom"
}

fun MyProfile.printName() = println(this.name)

fun main() {
    val myProfile = MyProfile()
    myProfile.printName() // Outputs: Tom
}

このように、MyProfile クラス内に直接メソッドが定義されていなくても、そうであるかのようにメソッドを追加することができます。

なお、サンプルコードに記載されているように、自身の class のプロパティには、this を使ってアクセスすることができます。

また、拡張プロパティで定義されたプロパティは、厳密に言えばそのクラスの内部に含まれているものではありませんが、クラス内で定義されたプロパティと同じように this を使ってアクセスすることが可能です。

下のコードは、拡張関数で拡張プロパティ(age)にアクセスしている例です。

Kotlin

class MyProfile {
    val name = "Tom"
}

val MyProfile.age
get () = 32

fun MyProfile.printAge() {
    println(this.age)
}

fun main() {
    val myProfile = MyProfile()
    myProfile.printAge() // Outputs: 32
}

拡張関数と拡張プロパティを組み合わせることで、より柔軟なカスタマイズが可能となります。

とは言え、自身で作成した class であれば、直接その class のコードを編集した方がより柔軟に機能を拡張できるので、そのようなケースでは拡張関数・拡張プロパティの出番はあまりないでしょう。

ということで、次のステップではもう少し実践的・実用的な拡張関数や拡張プロパティの使用例をご紹介したいと思います!

    POINT!
  1. ・拡張関数を利用することで、後からclassにメソッドを追加することができる!
  2. ・class自身のプロパティには this を使ってアクセスすることができる!
  3. ・拡張プロパティと拡張関数を組み合わせることも可能!

IntやStringを拡張する

Kotlinでは Int(整数)や、String(文字列)といった様々なデータ型が存在しますが、その実態は class です。

当然、StringInt の内部のコードを開発者が勝手に改変することはできませんが、拡張関数や拡張プロパティを利用すれば、独自の機能を追加することができます。

例えば、文字列を★マークで装飾した結果を得たい場合、次のように拡張プロパティを定義することができます。

Kotlin

val String.decorated
get() = "★☆ $this ☆★"

fun main() {
    val message = "Hello"
    println(message.decorated) // ★☆ Hello ☆★
}

上の例では、どのような文字列に対しても、String の拡張プロパティである decorated にアクセスすることで、★マークで装飾した結果を得ることができるようになっています。

このように、拡張プロパティは値の簡易的な装飾や変換などに利用されることが多いです。

そしてもう一つ、次は拡張関数の実用例を考えてみましょう。

Kotlinの Int 型には標準で様々なメソッドが用意されていますが、『特定の整数を二乗する』といったメソッドは意外にも用意されていません。

特定の整数を二乗した値を頻繁に得たい場合、その都度計算するのは面倒なので、拡張関数を定義してしまった方が得策です。

具体的には次のように拡張関数を定義・利用することができます。

Kotlin

fun Int.square() = this * this

val n = 5
val squared = n.square()

fun main() {
    println(squared) // Outputs: 25
}

このように、拡張関数を利用することで整数(Int)に対し、いつでも簡単にその数を二乗した結果を得ることができるようになります。

また、上の例のように特定の整数を二乗するだけであれば引数を渡す必要がないので、拡張プロパティを利用しても同じような機能を追加できます。

Kotlin

val Int.squared: Int
get() = this * this

ただ、数値を足したり掛けたりなどの計算を伴う場合は、どちらかと言うと拡張関数の方が直感的に分かりやすいと言えるかもしれません。(チームや個人の好みによると思います)

いずれにせよ、拡張関数や拡張プロパティを利用することで、StringInt といったデータ型にも様々なプロパティやメソッドを追加することができます。

アイデア次第で、コードの可読性を高めたり、コーディングの効率を良くしたりすることができるので、ぜひ拡張関数や拡張プロパティを利用して色々カスタマイズしてみてください!

    POINT!
  1. ・StringやIntといったデータ型(実態はclass)にも拡張関数や拡張プロパティを設定できる!
  2. ・拡張プロパティは、値の装飾や変換に利用されることが多い!
  3. ・拡張関数は、何らかの計算や複雑な処理を伴う場合に利用されることが多い!

« »

カテゴリーリンク

著者について- author profile -

ROYDOプロフィール写真
Michihiro

モバイルアプリ(iOS・Android)ディベロッパー&デザイナー

これまでに、可読性の高いカラーパターンを自動で生成するアプリや、『第3火曜日』といった形式で通知をスケジュールできるアプリなどを制作。

サブでWebデザイン・フロントエンドエンジニアとしても活動しています。

📝ツール・言語:JavaScript/React Native/Kotlin/Android Studio/Swift/SwiftUI

🎓資格:応用情報技術者/基本情報技術者/ウェブデザイン技能検定3級

Twitterアイコン Instagramアイコン