この記事で学べる知識:メソッドのオーバーライド
この記事の練習問題を解くために必要な知識:
基礎文法、制御構造、関数、コレクション(レッスン1~4)、クラスの定義と使用、プライマリコンストラクタ、セカンダリコンストラクタ、アクセス修飾子とカプセル化、クラスメンバとインスタンスメンバ、クラスの継承、メソッドのオーバーライド、クラスの拡張、抽象クラス、インターフェース、データクラス
<<前のページ | Kotlin記事一覧 |
次のページ>> |
Kotlinの「メソッドのオーバーライド」とは
この章ではKotlinにおける「メソッドのオーバーライド」の意味や使い方を学習します。用語の解説が不要な方はここをクリックして練習問題へ飛びましょう。
Kotlinにおいて「メソッドのオーバーライド」は、親クラスで定義されたメソッドを子クラスで再定義し、新たな挙動を与える機能です。
オブジェクト指向の特性を活かし、柔軟で再利用可能なコード設計に役立ちます。
メソッドのオーバーライドとは?
メソッドのオーバーライドとは、親クラスに定義されたメソッドを子クラスで同じ名前・引数を持つメソッドとして再定義することです。
これにより子クラスで特定の処理を上書きし、クラスの振る舞いを変更できます。
オーバーライドを使用するには、親クラスの関数がopen
修飾子を持ち、子クラスではoverride
キーワードを使用する必要があります。
メソッドのオーバーライドの基本構文
Kotlinで関数をオーバーライドする基本構文は以下の通りです。
open class Parent { // 親クラスとして使用されるParentクラスの定義 open fun greet() { // オーバーライドされることを想定したgreetメソッド println("Hello from Parent") } } class Child : Parent() { // Parentクラスを継承したChildクラスの定義 override fun greet() { // Parentクラスのgreetメソッドをオーバーライド println("Hello from Child") } }
- 親クラス
Parent
のメソッドgreet
はopen
キーワードを使用して再定義可能にしています。 - 子クラス
Child
ではoverride
キーワードを使用して新しい実装を提供しています。
メソッドのオーバーライドの使用例
メソッドのオーバーライドを活用した具体的なコード例を示します。
open class Animal { // 親クラスとして使用するAnimalクラスの定義 open fun makeSound() { // オーバーライドされることを想定したmakeSoundメソッドを定義 println("Some generic animal sound") } } class Dog : Animal() { // Animalクラスを継承したDogクラスを定義 override fun makeSound() { // AnimalクラスのmakeSoundメソッドをオーバーライド println("Bark!") } } class Cat : Animal() { // Animalクラスを継承したCatクラスを定義 override fun makeSound() { // AnimalクラスのmakeSoundメソッドをオーバーライド println("Meow!") } } fun main() { val animals: List<Animal> = listOf(Dog(), Cat(), Animal()) for (animal in animals) { animal.makeSound() // 各クラスに応じたサウンドが出力される } }
- 親クラス
Animal
は汎用的な動物の行動を定義します。 - 子クラス
Dog
とCat
はそれぞれ特定の動物の挙動をmakeSound
関数で再定義しています。 for
ループではリスト内の各インスタンスに応じて異なるメッセージが出力されます。
このコードを実行すると以下のように出力されます。
Bark! Meow! Some generic animal sound
オーバーライドの注意点
open
キーワード: 親クラスのメソッドはデフォルトでオーバーライドが禁止されています。オーバーライド可能にするにはopen
修飾子を付ける必要があります。override
キーワード: 子クラスでメソッドをオーバーライドする際は、必ずoverride
キーワードを使用します。これにより誤った再定義を防ぎます。- アクセス修飾子: 親クラスと子クラス間で関数の可視性に互換性が必要です。例えば、
protected
関数をpublic
に変更することは可能ですが、private
にすることはできません。
まとめ
Kotlinのメソッドのオーバーライドは、コードの柔軟性と再利用性を高める強力な機能です。
オーバーライドを正しく活用することで、親クラスの汎用性と子クラスの特化性を両立させ、オブジェクト指向プログラミングの真価を発揮できます。
メソッドのオーバーライドの練習問題
乗り物の動きを表現するプログラムを作成し、Kotlinの「メソッドのオーバーライド」を学びましょう。
基本となる「乗り物」のクラスを作成し、それを継承して「車」「船」「飛行機」の動きをそれぞれ異なる方法で実装します。
最後にこれらの乗り物の動きを表示するプログラムを作成してください。
この問題の要件
以下の要件に従ってコードを完成させてください。
- クラス Vehicle を作成すること。
- move() という関数を定義し、「乗り物が移動します」と出力すること。
- クラス Car を作成し、Vehicle クラスを継承すること。
- move() 関数をオーバーライドし、「車が道路を走ります」と出力すること。
- クラス Boat を作成し、Vehicle クラスを継承すること。
- move() 関数をオーバーライドし、「船が水上を進みます」と出力すること。
- クラス Airplane を作成し、Vehicle クラスを継承すること。
- move() 関数をオーバーライドし、「飛行機が空を飛びます」と出力すること。
- main関数 を作成すること。
- Vehicle 型のリストを作成し、Car、Boat、Airplane のインスタンスをリストに追加すること。
- すべてのインスタンスで move() 関数を呼び出し、動作を表示すること。
ただし、以下のような実行結果となるコードを書くこと。
*****↓↓正解コードの実行結果の例↓↓*****
車が道路を走ります 船が水上を進みます 飛行機が空を飛びます
この問題を解くヒント
1からコードを組み立てることが難しい場合は、以下のヒントを開いて参考にしましょう。
正解のコードは上から順に以下のような構成となっています。
(※下記の□はコード内のインデントを表しています)
1:Vehicleクラスの定義
□ moveメソッドの定義(open修飾子付き)
2:Carクラスの定義(Vehicleクラスを継承)
□ moveメソッドをオーバーライド
3:Boatクラスの定義(Vehicleクラスを継承)
□ moveメソッドをオーバーライド
4:Airplaneクラスの定義(Vehicleクラスを継承)
□ moveメソッドをオーバーライド
5:main関数の定義
□ Vehicle型のリストを作成し、Car、Boat、Airplaneのインスタンスを格納
□ forループによりリストの各要素について処理
□ □ moveメソッドを呼び出す
以下のコードをコピーし、コメントに従ってコードを完成させて下さい。
// 基本的な乗り物のクラス open class Vehicle { /*【穴埋め問題1】 ここにmoveメソッドを定義し、「乗り物が移動します」と出力するコードを書いてください。 */ } // 車クラス(Vehicleクラスを継承) class Car : Vehicle() { /*【穴埋め問題2】 ここにmoveメソッドをオーバーライドし、「車が道路を走ります」と出力するコードを書いてください。 */ } // 船クラス(Vehicleクラスを継承) class Boat : Vehicle() { /*【穴埋め問題3】 ここにmoveメソッドをオーバーライドし、「船が水上を進みます」と出力するコードを書いてください。 */ } // 飛行機クラス(Vehicleクラスを継承) class Airplane : Vehicle() { /*【穴埋め問題4】 ここにmoveメソッドをオーバーライドし、「飛行機が空を飛びます」と出力するコードを書いてください。 */ } fun main() { // Vehicle型のリストを作成 val vehicles: List<Vehicle> = listOf(Car(), Boat(), Airplane()) // 各乗り物に応じた動作を表示 for (vehicle in vehicles) { // 【穴埋め問題5】ここでvehicleオブジェクトのmoveメソッドを呼び出してください。 } }
以上がこの問題の穴埋めコードです。
このヒントを見てもまだ回答を導き出すのが難しいと感じる場合は、先に正解のコードと解説を見て内容を理解するようにしましょう。
練習問題の解答と解説
この問題の一つの正解例とそのコードの解説を以下に示します。
正解コードの例
例えば以下のようなプログラムが考えられます。
// 基本的な乗り物のクラス open class Vehicle { // 乗り物の走行方法を表す関数 open fun move() { println("乗り物が移動します") } } // 車クラス(Vehicleクラスを継承) class Car : Vehicle() { // moveメソッドをオーバーライドして車特有の動作を実装 override fun move() { println("車が道路を走ります") } } // 船クラス(Vehicleクラスを継承) class Boat : Vehicle() { // moveメソッドをオーバーライドして船特有の動作を実装 override fun move() { println("船が水上を進みます") } } // 飛行機クラス(Vehicleクラスを継承) class Airplane : Vehicle() { // moveメソッドをオーバーライドして飛行機特有の動作を実装 override fun move() { println("飛行機が空を飛びます") } } fun main() { // Vehicle型のリストを作成 val vehicles: List<Vehicle> = listOf(Car(), Boat(), Airplane()) // 各乗り物に応じた動作を表示 for (vehicle in vehicles) { // オーバーライドされたメソッドが呼び出されることを確認 vehicle.move() } }
正解コードの解説
このプログラムではKotlinで「メソッドのオーバーライド」を学ぶことを目的としています。
プログラム全体をブロックごとに分け、使用されている文法を初心者にもわかりやすく解説します。
クラス Vehicle
の定義
open class Vehicle { open fun move() { println("乗り物が移動します") } }
open
修飾子: Kotlinではクラスやメソッドを継承可能にするにはopen
を付ける必要があります。Vehicle
クラスは他のクラスに継承されるためopen
を指定しています。move
メソッド: 基本的な乗り物の動きを表現しています。このメソッドはオーバーライドされるためopen
を付けています。
Car
, Boat
, Airplane
クラスの定義と move
メソッドのオーバーライド
class Car : Vehicle() { override fun move() { println("車が道路を走ります") } } class Boat : Vehicle() { override fun move() { println("船が水上を進みます") } } class Airplane : Vehicle() { override fun move() { println("飛行機が空を飛びます") } }
class Car : Vehicle()
: クラスCar
はVehicle
を継承しています。:
を使用して親クラスを指定します。override
修飾子: 親クラスのメソッドを再定義する際に使います。このコードではそれぞれの乗り物に特有の動きを表現するため、move
メソッドをオーバーライドしています。
main
関数でリストを使用して動作を表示
fun main() { val vehicles: List<Vehicle> = listOf(Car(), Boat(), Airplane()) for (vehicle in vehicles) { vehicle.move() } }
List
型: Kotlinのコレクション型の一つで複数の要素を保持できます。この場合、Vehicle
型のリストを作成しています。listOf(Car(), Boat(), Airplane())
:Car
、Boat
、Airplane
のインスタンスをリストに追加します。for
文: リストの各要素に対して繰り返し処理を行います。vehicle.move()
によって、それぞれのオーバーライドされたmove
メソッドが呼び出されます。
まとめ
このプログラムではKotlinの「継承」と「メソッドのオーバーライド」の基礎を学びました。
実際にコードを動かしながら学ぶことで、理解が深まるでしょう!
次のステップとして自分で新しい乗り物を追加して、さらに異なる動きをプログラムに実装してみてください。
これによってオーバーライドの応用力が高まります。
<<前のページ |
Kotlin記事一覧 |
次のページ>> |
この記事への質問・コメント
この記事を作成するにあたりAIを活用しています。
問題ないことは確認していますが、もし間違いや表現の違和感などありましたら、ご指摘頂けると大変助かります。
Kotlinのテキスト&問題集トップへ戻る
トップページへ戻る