0Pricing
Kotlin Academy · レッスン

拡張関数:構文とディスパッチ規則

拡張関数を記述し、静的ディスパッチの仕組みを理解します。

「拡張関数:構文とディスパッチ規則」はCoddyKit上の無料Kotlin Academyレッスンです。 これはレッスン1/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはKotlin Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Kotlin Academyコースには全4レッスンが含まれています。

拡張関数とは

拡張関数を使うと、既存のクラスを変更したり継承したりせずに、新しい関数を追加できます。

拡張関数の基本構文

拡張する型を関数名の前に付けます。これを「レシーバー型」と呼びます。
fun String.shout(): String = uppercase() + "!"
println("hello".shout())  // HELLO!
fun Int.isEven() = this % 2 == 0
println(4.isEven())  // true

拡張関数内の this

拡張関数内では、'this' はレシーバーオブジェクトを参照します。
fun List<Int>.secondOrNull(): Int? {
    return if (size >= 2) this[1] else null
}
println(listOf(10, 20, 30).secondOrNull())  // 20
println(listOf(5).secondOrNull())           // null

静的ディスパッチ:拡張関数はオーバーライドされない

拡張関数は、宣言された型に基づいてコンパイル時に静的に解決され、仮想関数ではありません。
open class Base
class Child : Base()
fun Base.greet() = "Hello from Base"
fun Child.greet() = "Hello from Child"

val obj: Base = Child()
println(obj.greet())  // "Hello from Base" (static dispatch!)

拡張関数とメンバー関数

クラスに拡張関数と同じシグネチャのメンバー関数がある場合は、常にメンバー関数が優先されます。
class Greeter {
    fun hello() = "member hello"
}
fun Greeter.hello() = "extension hello"  // shadowed!
println(Greeter().hello())  // "member hello"

Nullable レシーバーの拡張関数

Nullable 型を拡張することもできます。拡張関数内では、'this == null' のチェックで null を処理してください。
fun String?.orEmpty() = this ?: ""
fun Any?.toStringSafe() = this?.toString() ?: "null"
println(null.orEmpty())  // ""
println(42.toStringSafe())  // "42"

可視性とスコープ

拡張関数は、トップレベル(グローバル)、クラス内(メンバー拡張)、またはファイル内で定義できます。通常の可視性ルールに従います。
// Top-level extension:
fun List<String>.joinUppercase() = joinToString { it.uppercase() }
// Private to file:
private fun String.clean() = trim().lowercase()

Companion Object の拡張

Companion Object に拡張関数を追加して、クラスレベルの名前空間を拡張します。
class User(val name: String) {
    companion object
}
fun User.Companion.guest() = User("Guest")
val guest = User.guest()

標準ライブラリ型の拡張

組み込み型を含む、あらゆる型を拡張できます。
fun Double.roundTo(decimals: Int): Double {
    val factor = Math.pow(10.0, decimals.toDouble())
    return Math.round(this * factor) / factor
}
println(3.14159.roundTo(2))  // 3.14

拡張関数の整理

型ごとの拡張関数は専用ファイルにまとめます。例として、StringExtensions.kt や DateExtensions.kt があります。
// StringExtensions.kt
fun String.titleCase() = split(" ")
    .joinToString(" ") {
        it.replaceFirstChar { c -> c.uppercase() }
    }
println("hello world".titleCase())  // Hello World

拡張関数から private メンバーにはアクセスできない

拡張関数からアクセスできるのは public と internal のメンバーだけで、private や protected のメンバーにはアクセスできません。
class Secret {
    private val key = "hidden"
    val name = "public"
}
fun Secret.reveal() {
    println(name)  // OK
    // println(key)  // Error: key is private
}

クイックチェック

クラスのメンバー関数と拡張関数のシグネチャが同じ場合、どちらが呼び出されますか?

まとめ

拡張関数を使うと、変更を加えずに任意のクラスへ振る舞いを追加できます。拡張関数は静的にディスパッチされ、オーバーライドはできません。メンバー関数は拡張関数より優先されます。null 安全なヘルパーには Nullable レシーバーを使用してください。次は拡張プロパティです。

よくある質問

「拡張関数:構文とディスパッチ規則」レッスンは無料ですか?

はい。「拡張関数:構文とディスパッチ規則」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Kotlin Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Kotlin Academyコースには全4レッスンが含まれています。

「拡張関数:構文とディスパッチ規則」で何を学びますか?

拡張関数を記述し、静的ディスパッチの仕組みを理解します。 ブラウザで直接実行するハンズオンコードでKotlin Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

Kotlin Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのKotlin Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン1/4です。

「拡張関数:構文とディスパッチ規則」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このKotlin Academyレッスンでコードを書いて実行できますか?

はい。すべてのKotlin Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. 拡張関数:構文とディスパッチ規則
  2. 拡張プロパティと計算拡張
  3. スコープ付き拡張とcompanion拡張
  4. 実践的な拡張:Context、View、Stringヘルパー
← Kotlin Academyに戻る