デフォルトメソッド
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) : Boxmainの内部では:
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チャレンジ
簡単インターフェース 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"}")
}
}
このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。
オブジェクト指向プログラミングのすべてのレッスン
自分で練習してみよう: Kotlinプレイグラウンド