表示テーマ
6. 継承とoverride
学習目標: : Block(...)とoverride fun stepOn(...)の役割を説明できる。
Minecraftには、ブロックを表すBlockクラスがあります。継承を使うと、既存のブロックの仕組みを利用しながら、踏まれたときの処理を変更できます。
小さなモデルで試す
kotlin
open class Block {
open fun stepOn() {
println("普通の床")
}
}
class JumpPad : Block() {
override fun stepOn() {
println("ジャンプ!")
}
}これは学習用に作ったBlockです。Minecraftの本物のAPIとは引数が違います。
JumpPad : Block()は「JumpPadはBlockを継承する」と読みます。overrideは親で定義された関数の実装を上書きする印です。
Kotlinで自分が書くクラスと関数は、通常は継承・上書きできません。親のopenがそれを許可します。既存のMinecraftのクラスを使うときは、そのAPIが提供する継承可能な関数に従います。
予想:何も上書きしなかったら?
演習の初期状態では、JumpPadの中に関数を書いていません。その状態でJumpPad().stepOn()を呼ぶと、親の実装が使われて「普通の床」と出ます。
踏まれたときの動きを変えよう
JumpPadのstepOnを上書きして、2行目だけ「ジャンプ!」と表示する。
目標の出力
普通の床 ジャンプ!
自動採点ではありません。入力を変えた場合も結果を確かめてください。
ヒント 1
親と同じ名前の関数を、overrideを付けて子クラスに書こう。
ヒント 2
override fun stepOn() { println("ジャンプ!") }
解答例
open class Block {
open fun stepOn() {
println("普通の床")
}
}
class JumpPad : Block() {
override fun stepOn() {
println("ジャンプ!")
}
}
fun main() {
Block().stepOn()
JumpPad().stepOn()
}解答例を閉じて、もう一度自分で書いてみてください。これ以外の正しい書き方もあります。
親の処理も使いたいとき
kotlin
override fun stepOn() {
super.stepOn()
println("ジャンプ!")
}super.stepOn()は親の実装を呼びます。この例では「普通の床」の次に「ジャンプ!」と出ます。書かなければ、その上書きした関数の中で親の処理が自動的に実行されるわけではありません。
MinecraftのstepOnが受け取る引数
MyParkourのstepOnは、世界を表すlevel、位置のpos、ブロックの状態のstate、踏んだものを表すentityを受け取ります。Minecraft側が呼び出すときに、その場の情報を渡します。
名前だけでなく、引数の型なども親の定義に合わせる必要があります。IDEのoverride補完を使い、そのプロジェクトで利用しているAPIの定義を確認しましょう。