【Kotlin】レッスン5-8:メソッドのオーバーライドの仕組みと使い方

一つ前のページではクラスの継承について学習しました。
今回は メソッドのオーバーライド について見ていきましょう。
Lesson1:基礎文法編
Lesson2:制御構造編
Lesson3:関数編
Lesson4:コレクション編
Lesson5:オブジェクト指向編
・Lesson5-1:クラスの基本を理解しよう
・Lesson5-2:プライマリコンストラクタを理解しよう
・Lesson5-3:セカンダリコンストラクタを理解しよう
・Lesson5-4:ふたつのコンストラクタを使いこなそう
・Lesson5-5:アクセス修飾子とカプセル化を理解しよう
・Lesson5-6:静的メンバとインスタンスメンバを理解しよう
・Lesson5-7:クラスの継承を理解しよう
・Lesson5-8:メソッドのオーバーライドを理解しよう ◁今回はココ
・Lesson5-9:クラスを拡張しよう
・Lesson5-10:抽象クラスを理解しよう
・Lesson5-11:インターフェースを理解しよう
・Lesson5-12:データクラスを理解しよう
・確認問題5-☆1:モンスター捕獲ゲームを作ろう
・確認問題5-☆2:マルバツゲームを作ろう
・確認問題5-☆3:石取りゲームを作ろう
メソッドのオーバーライド|定義・構文・注意点を解説

Kotlinにおいて「メソッドのオーバーライド」は、親クラスで定義されたメソッドを子クラスで再定義し、新たな挙動を与える機能です。
オブジェクト指向の特性を活かし、柔軟で再利用可能なコード設計に役立ちます。

オーバーライドとは何か?|概要とコードの書き方
メソッドの オーバーライド とは、親クラスに定義されたメソッドを子クラス側から再定義することです。
これにより子クラスで特定の処理を上書きし、クラスの振る舞いを変更できます。
オーバーライドを使用するには、親クラスのメソッドが open
修飾子 を持ち、子クラスでは override
キーワード を使用する必要があります。
オーバーライドの基本構文は以下の通りです。
open class 親クラス名 { // 親クラスの定義 open fun メソッド名() { // オーバーライドされることを想定したメソッドの定義 // このメソッドの処理 } } class 子クラス名 : 親クラス名() { // 親クラスを継承した子クラスの定義 override fun メソッド名() { // メソッドのオーバーライド // このメソッドの処理 } }
オーバーライドさせるには、それぞれのメソッドが同じ名前である必要があります。
これにより、子クラス側から親クラスのメソッドをオーバーライドする準備が整いました。
オーバーライドの使用コード例と注意点
メソッドのオーバーライドを活用した具体的なコード例を示します。
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 animal = Animal() // 親クラスのインスタンス生成 val dog = Dog() // 子クラスDogのインスタンス生成 val cat = Cat() // 子クラスCatのインスタンス生成 animal.makeSound() // 出力:Some generic animal sound dog.makeSound() // 出力:Bark! cat.makeSound() // 出力:Meow! }
main
関数でそれぞれのクラスのインスタンスを生成し、makeSound
メソッドを呼び出しています。
このとき、親クラスのインスタンスでは親クラスのメソッドが、子クラスのインスタンスではオーバーライドされた子クラス独自のメソッドが実行されます。
共通のインターフェース(メソッド名)を保ちつつ、各クラスごとに異なる動作を実装できるのが継承とオーバーライドの大きなメリットです。
このコードを実行すると以下のように出力されます。
Some generic animal sound Bark! Meow!
オーバーライドを使用する際には、以下の点に注意しましょう。
open
キーワード: 親クラスのメソッドはデフォルトでオーバーライドが禁止されています。オーバーライド可能にするにはopen
修飾子を付ける必要があります。override
キーワード: 子クラスでメソッドをオーバーライドする際は、必ずoverride
キーワードを使用します。これにより誤った再定義を防ぎます。- アクセス修飾子: 親クラスと子クラス間で関数の可視性に互換性が必要です。例えば、
protected
関数をpublic
に変更することは可能ですが、private
にすることはできません。
まとめ|オーバーライドで実現する多様なふるまい
オーバーライドは、親クラスで定義されたメソッドを子クラスで自由に再定義できる、継承の大きな強みのひとつです。
これにより、共通のインターフェースを保ちながら、クラスごとに異なるふるまいを実装できます。
オーバーライドを正しく活用することで、拡張性や柔軟性の高い設計が可能になり、
プログラム全体の保守性や再利用性も大きく向上します。
ぜひ今回の内容を参考に、実際の開発でもオーバーライドを積極的に活用してみてください。
練習問題|メソッドのオーバーライドを使った多態性の理解を深めよう

乗り物の動きを表現するプログラムを作成しましょう。
基本となる「乗り物」のクラスを作成し、それを継承して「車」「船」「飛行機」の動きをそれぞれ異なる方法で実装します。
最後にこれらの乗り物の動きを表示するプログラムを作成してください。
この問題の要件
以下の要件に従ってコードを完成させてください。
- クラス Vehicle を作成すること。
- move() という関数を定義し、「乗り物が移動します」と出力すること。
- クラス Car を作成し、Vehicle クラスを継承すること。
- move() 関数をオーバーライドし、「車が道路を走ります」と出力すること。
- クラス Boat を作成し、Vehicle クラスを継承すること。
- move() 関数をオーバーライドし、「船が水上を進みます」と出力すること。
- クラス Airplane を作成し、Vehicle クラスを継承すること。
- move() 関数をオーバーライドし、「飛行機が空を飛びます」と出力すること。
- main関数 を作成すること。
- Vehicle 型のリストを作成し、Car、Boat、Airplane のインスタンスをリストに追加すること。
- すべてのインスタンスで move() 関数を呼び出し、動作を表示すること。
ただし、以下のような実行結果となること。
車が道路を走ります 船が水上を進みます 飛行機が空を飛びます
この問題を解くヒント
1からコードを組み立てることが難しい場合は、以下のヒントを開いて参考にしましょう。
- ヒント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メソッドを呼び出す
- ヒント2【穴埋め問題にする】
-
以下のコードをコピーし、コメントに従ってコードを完成させて下さい。
// 基本的な乗り物のクラス 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() } }
- 正解コードの解説
-
コードをブロックごとに分割して解説します。
クラス
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
メソッドが呼び出されます。
- サイト改善アンケート & ご指摘/ご質問
-
本サイトでは、みなさまの学習をよりサポートできるサービスを目指しております。
そのため、みなさまの「プログラミングを学習する理由」などを アンケート 形式でお伺いしています。また記事の内容に関する ご指摘 や ご質問 もお待ちしています。