Menu
Coddy logo textTech

デフォルトメソッド

CoddyのKotlinジャーニー「オブジェクト指向プログラミング」セクションの一部。レッスン 23/57。

インターフェースメソッドには本体を持たせることができます。このデフォルト実装は、オーバーライドしないすべてのクラスで使用されます。

interface Greeter {
    val name: String
    fun greet() = "Hello, I am $name"
}
class Robot(override val name: String) : Greeter
class Pirate(override val name: String) : Greeter {
    override fun greet() = "Ahoy! $name here"
}

mainの中で:

println(Robot("R2").greet())
println(Pirate("Anne").greet())

出力:

Hello, I am R2
Ahoy! Anne here

デフォルトメソッドは、インターフェースの他のメンバーを使って記述されます。クラスは異なる少数のメンバーを提供し、残りを受け取ります。

interface Priced {
    val cents: Int
    fun formatted() = "$%d.%02d".format(cents / 100, cents % 100)
    fun isAffordable(budget: Int) = cents <= budget
}
class Coffee : Priced {
    override val cents = 450
}

mainの内部では:

val c = Coffee()
println(c.formatted())
println(c.isAffordable(400))

出力:

$4.50
false

プロパティにはデフォルトのゲッターを定義できますが、インターフェースにはバッキングフィールドがないため、値を格納できません。初期化子を持つプロパティはコンパイルできませんが、値を計算するゲッターは使用できます。

interface Box {
    val width: Int
    val height: Int
    val area: Int
        get() = width * height
    // val count = 0      // error: インターフェースではプロパティの初期化子は許可されていません
}
class Tile(override val width: Int, override val height: Int) : Box

mainの内部では:

println(Tile(3, 4).area)

出力:

12

オーバーライドでは、デフォルト実装を使用することもできます。クラス内で、super.method()はインターフェースのバージョンを呼び出します:

interface Priced {
    val cents: Int
    fun formatted() = "$%d.%02d".format(cents / 100, cents % 100)
}
class Coffee : Priced {
    override val cents = 450
    override fun formatted() = "coffee " + super.formatted()
}

mainの内部では:

println(Coffee().formatted())

出力:

coffee $4.50
challenge icon

チャレンジ

簡単

インターフェース Priced は price(セント単位)を持ちます。$4.50 を返すデフォルトの formatted() と、価格が予算以下であるかどうかを返すデフォルトの isAffordable(budget) を与えてください。Coffee の価格は 450 で、super を通じてデフォルト実装を再利用しながら、formatted() を coffee $4.50 に置き換えます。Sandwich(price) は両方のデフォルト実装を使用します。

提供されているコードはセント単位の予算を読み取り、その後に coffee または sandwich,650 の行を読み取ります。各項目について formatted() と、yes または no を出力します。

コードは Priced.kt、Coffee.kt、Sandwich.kt に記述します。Main.kt には提供された入出力コードが含まれており、編集できません。

自分で試してみよう

fun main() {
    // 提供された入出力コード: そのままにしておく
    val input = generateSequence(::readLine).toList()
    val budget = input[0].toInt()
    for (line in input.drop(1)) {
        val p = line.split(",")
        val item: Priced = if (p[0] == "coffee") Coffee() else Sandwich(p[1].toInt())
        println("${item.formatted()} ${if (item.isAffordable(budget)) "yes" else "no"}")
    }
}
quiz icon腕試し

このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。

オブジェクト指向プログラミングのすべてのレッスン

自分で練習してみよう: Kotlinプレイグラウンド