Kotlinチュートリアル - 9 ポリモーフィズム

オブジェクト指向プログラミングにはポリモーフィズムという原則があります。ポリモーフィズムは、多くのクラスが異なる方法で実装できる振る舞いのメカニズムです。例えば、人間と猫のエンティティはどちらも歩く振る舞いを持っていますが、それぞれ異なる方法で歩きます。人間は二本の足で歩きますが、猫は四本の足で歩きます。

シールドクラスを作成する

シールドクラスはシールドクラスを継承する多くのサブクラスを含むクラスです。基本的にはシールドクラスはenumと同一ですが、多くのクラスを含むことができます。シールドクラスは抽象クラスであるため、シールドクラスからオブジェクトを作成またはインスタンス化することはできません。

これがシールドクラスを作成する基本的な構文です。

sealed class class_name(attributes,...) {
    // サブクラスをたくさん作る..
}

この他にも、以下のような構文でシールドクラスを作成することができます。

sealed class class_name
// サブクラスをたくさん作る..

この例では、Vehicle.ktファイルの中にシールドクラスが作成されています。

// Vehicleというシールドクラスを作成する
sealed class Vehicle
// Vehicleクラスを継承する二つのデータクラスを作成する
data class Motorcycle(val manufacturer: String, val type: String): Vehicle()
data class Car(val manufacturer: String, val type: String): Vehicle()

// Vehicleクラスを継承するクラスから呼び出せるrun()メソッドを作成する
fun Vehicle.run() {
    // 特定のクラスに基づいてrun()の実装を定義する
    when(this) {
        is Motorcycle -> println("二輪で走る")
        is Car -> println("四輪で走る")
    }
}

シールドクラスであるVehicleを継承するMotorcycleクラスのオブジェクトを作成します。

fun main() {
    // Motorcycleクラスのオブジェクトを作成する
    val motorcycle = Motorcycle("Honda","CBR")
    // run()メソッドを呼び出す
    motorcycle.run()
}

出力

二輪で走る

上記のコードに基づき、Vehicleというシールドクラスが作成され、MotorcycleCarを含む多くのサブクラスがあります。

Vehicleクラス内のrun()メソッドの実装は、whenの条件選択に基づいて特定のクラスに基づいて定義されています。

// Vehicleクラスを継承するクラスから呼び出せるrun()メソッドを作成する
fun Vehicle.run() {
    // 特定のクラスに基づいてrun()の実装を定義する
    when(this) {
        is Motorcycle -> println("二輪で走る")
        is Car -> println("四輪で走る")
    }
}

インターフェースを作成する

インターフェースはたくさんの抽象メソッドだけを含んだクラスです。インターフェースは、クラスが満たさなければならない契約を定義するために使用することができます。これがインターフェースを作成する基本的な構文です。

interface interface_name {
    // 抽象メソッドをたくさん作る...
}

この例では、ShapeInterface.ktファイルにShapeInterfaceと呼ばれるインターフェースが作成されています。

interface ShapeInterface {
    fun getArea(): Double
}

作成済みのインターフェースはCircleクラスによって実装されています。

// ShapeInterfaceを実装するCircleクラスを作成する
class Circle(val radius: Double): ShapeInterface {

    // getArea()メソッドが実装される
    override fun getArea(): Double {
        return Math.PI * radius * radius
    }
}

main()メソッドでCircleクラスのオブジェクトが作成されます。

fun main() {
    // Circleクラスのオブジェクトを作成する
    val circle = Circle(7.0)
    // getArea()メソッドを呼び出す
    val area = circle.getArea()
    // getArea()メソッドからの結果を出力する
    println("円の面積: $area")
}

出力

円の面積: 153.93804002589985

上記のコードに基づいて、ShapeInterfaceという名前のインターフェースが作成されており、getArea()という抽象メソッドが含まれています。CircleクラスはShapeInterfaceを実装しているため、このインターフェース内のすべてのメソッドを実装する必要があります。main()メソッドでは、Circleクラスのオブジェクトが作成され、その後getArea()メソッドが呼び出されます。

クラスは多くのインターフェースを実装することができます。この例では、Circleクラスは2つのインターフェースを実装しています。

新しいインターフェースがEntityInterface.ktファイルでEntityInterfaceと呼ばれるものとして作成されています。

interface EntityInterface {
    fun getInfo()
}

2つのインターフェースはCircleクラスに実装されています。

// 2つのインターフェースを実装するCircleクラスを作成する
class Circle(val radius: Double): ShapeInterface, EntityInterface {

    // getArea()メソッドが実装される
    override fun getArea(): Double {
        return Math.PI * radius * radius
    }

    // getInfo()メソッドが実装される
    override fun getInfo() {
        println("半径: $radius")
        println("円の面積: ${getArea()}")
    }
}

main()メソッドでCircleクラスのオブジェクトが作成されます。

fun main() {
    // Circleクラスのオブジェクトを作成する
    val circle = Circle(7.0)
    // getInfo()メソッドを呼び出す
    circle.getInfo()
}

出力

半径: 7.0
円の面積: 153.93804002589985

ノート

  • シールドクラスは、シールドクラスを継承する多くのクラスを作るために使用できます。

  • インターフェースは、特定のクラスが遵守しなければならない契約を定義するために使用できます。

これはこのブログでのKotlin基本チュートリアルシリーズの最終部分です。このKotlin基本チュートリアルシリーズがKotlinプログラミング言語の学習に役立てば幸いです😀。

参考情報

  • シールドクラスの詳細については、このリンクをご覧ください。

  • インターフェースの詳細については、このリンクをご覧ください。

  • シールドクラスの使用例については、このリンクをご覧ください。

この記事がKotlinプログラミング言語の学習に役立てば幸いです。何か意見やコメントがありましたら、以下のディスカッションセクションにてご意見をお聞かせください。

こちらの記事はdev.toの良い記事を日本人向けに翻訳しています。
https://dev.to/nadirbasalamah/kotlin-tutorial-9-polymorphism-43l5