【Java】レッスン5-06:メソッドのオーバーライドとは?仕組みと使い方を基礎から解説

一つ前のページではクラスの継承について学習しました。
今回は メソッドのオーバーライド について見ていきましょう。
Lesson1:基礎文法編
Lesson2:制御構造編
Lesson3:メソッド編
Lesson4:コレクション編
Lesson5:クラス編
・Lesson5-1:クラスの基本を確認しよう
・Lesson5-2:コンストラクタを理解しよう
・Lesson5-3:カプセル化を理解しよう
・Lesson5-4:クラスメンバとインスタンスメンバを理解しよう
・Lesson5-5:クラスの継承を理解しよう
・Lesson5-6:メソッドのオーバーライドを理解しよう ◁今回はココ
・Lesson5-7:抽象クラスを理解しよう
・Lesson5-8:インターフェースを理解しよう
・確認問題5-☆1:モンスター捕獲ゲームを作ろう
・確認問題5-☆2:モンスターとのバトルゲームを作ろう
・確認問題5-☆3:マルバツゲーム(Tic-Tac-Toe)を作成しよう
Javaのメソッドオーバーライドとは?基本から丁寧に解説

メソッドのオーバーライドは、継承したクラスのメソッドを子クラスで再定義する技術です。
オーバーライドを使用することで、親クラスから継承されたメソッドを子クラスで新しい動作に変えることができます。
これによりプログラム全体の柔軟性と再利用性が高まります。
メソッドのオーバーライドを理解するためには「クラスの継承」の知識が必須となりますので、クラスの継承が分からいない人はまず↓↓の記事を確認しましょう。


オーバーライドの定義と基本的な考え方
オーバーライドは親クラスに定義されたメソッドと同じ名前、引数、戻り値を持つメソッドを子クラスで再定義することを指します。
このときメソッドのシグネチャ(メソッド名、引数の数と型、戻り値の型)は親クラスのメソッドと一致している必要があります。
また親クラスのメソッドに@Override
アノテーションを追加すると、オーバーライドであることが明示され、エラーが検出しやすくなります。
継承との違いと親子クラスでの活用法
オーバーライドはクラスの継承を前提とした技術です。
親クラスのメソッドをそのまま利用するだけでなく、子クラス独自の動作を追加したい場合に役立ちます。
たとえば動物クラスに定義された「鳴く」メソッドを、犬や猫といった子クラスでオーバーライドすることで、それぞれの動物に応じた鳴き声を出すように変更することができます。
class Animal { //親クラス void makeSound() { //makeSoundメソッドの定義 System.out.println("Some generic animal sound"); } } class Dog extends Animal { //子クラス @Override //Overrideアノテーション void makeSound() { //親クラスと同じ名前のメソッド System.out.println("Woof"); } } class Cat extends Animal { //子クラス @Override //Overrideアノテーション void makeSound() { //親クラスと同じ名前のメソッド System.out.println("Meow"); } }
この例ではAnimal
クラスを継承したDog
とCat
クラスが、それぞれの動物の鳴き声を出すようにmakeSound
メソッドをオーバーライドしています。
これによりDog
オブジェクトのmakeSound
メソッドを呼び出すと「Woof」、Cat
オブジェクトのmakeSound
メソッドを呼び出すと「Meow」と表示されます。
動物クラスで学ぶオーバーライドの使用例
オーバーライドは共通のメソッドを持つ複数の子クラスに対して異なる動作を実現する際に効果的です。
次のコード例では、動物園のシステムで各動物が異なる鳴き声を出すケースを示しています。
class Zoo { public static void main(String[] args) { Animal animal1 = new Dog(); Animal animal2 = new Cat(); animal1.makeSound(); // 出力: Woof animal2.makeSound(); // 出力: Meow } }
この例ではZoo
クラスの中でDog
とCat
クラスをAnimal
型の変数に代入していますが、各オブジェクトのmakeSound
メソッドを呼び出すと、それぞれのクラスにオーバーライドされたメソッドが実行されます。
これにより動物ごとに異なる鳴き声を表現でき、オブジェクト指向の多態性(ポリモーフィズム)が実現されます。
アクセス修飾子や例外の扱い方に注意しよう
オーバーライドにはいくつかのルールがあります。
オーバーライドするメソッドは、親クラスのメソッドと同じかそれより広いアクセス修飾子である必要があります。
たとえば親クラスでprotected
と指定されている場合、オーバーライドする子クラスのメソッドはprotected
またはpublic
である必要があります。private
やfinal
で宣言されたメソッドはオーバーライドできないため注意が必要です。
また例外についてもルールがあります。
親クラスのメソッドが特定の例外をスローする場合、子クラスのオーバーライドメソッドは同じ例外か、それよりも狭い範囲の例外をスローする必要があります。
オーバーライドの重要ポイントを総まとめ
メソッドのオーバーライドは、クラスの継承を活用してクラスごとの動作を実装する重要な技術です。
オーバーライドを使うことで、親クラスのメソッドを子クラスで独自に実装し、より柔軟で再利用性の高いコードを作成できます。
クラスの継承との関係やルールを正しく理解し、効果的に活用していきましょう。
練習問題|メソッドのオーバーライドで動物ごとの鳴き声を表示しよう

動物の鳴き声を表示するプログラムを作成しましょう。
このプログラムでは動物の基本的な鳴き声を表示する「動物クラス」と、それを継承して「犬クラス」を作成します。
犬クラスではメソッドのオーバーライドを使って、犬が鳴くときの特有の鳴き声を表示します。
この問題の要件
以下の要件に従ってコードを完成させてください。
Animal
クラスを作成し、sound
メソッドを定義すること。sound
メソッドは「動物は音を出します」と表示すること。
Animal
クラスを継承したDog
クラスを作成し、sound
メソッドをオーバーライドすること。- オーバーライドした
sound
メソッドでは「犬は「ワンワン」と鳴きます」と表示すること。
- オーバーライドした
Main
クラス内で以下の処理を行うこと。Animal
クラスのインスタンスを作成し、sound
メソッドを呼び出すこと。Dog
クラスのインスタンスを作成し、sound
メソッドを呼び出すこと。
ただし、以下のような実行結果となること。
動物は音を出します 犬は「ワンワン」と鳴きます
この問題を解くヒント
1からコードを組み立てることが難しい場合は、以下のヒントを開いて参考にしましょう。
- ヒント1【コードの構成を見る】
-
正解のコードは上から順に以下のような構成となっています。
(※下記の□はコード内のインデントを表しています)1:Animalクラスの定義
□ soundメソッドの定義
□ □ 「動物は音を出します」と出力する2:Dogクラスの定義(Animalクラスを継承)
□ soundメソッドのオーバーライド
□ □ 「犬は「ワンワン」と鳴きます」と出力する3:Mainクラスの定義
□ mainメソッドの定義
□ □ AnimalクラスのインスタンスgenericAnimalを作成
□ □ genericAnimalのsoundメソッドを呼び出す
□ □ DogクラスのインスタンスmyDogを作成
□ □ myDogのsoundメソッドを呼び出す
- ヒント2【穴埋め問題にする】
-
以下のコードをコピーし、コメントに従ってコードを完成させて下さい。
// 親クラス:動物(Animal) class Animal { // 動物の鳴き声を表示するメソッド public void sound() { System.out.println("動物は音を出します"); } } // 子クラス:犬(Dog) - Animalクラスを継承 class Dog extends Animal { /* 【穴埋め問題1】 ここにsoundメソッドをオーバーライドし、「犬は「ワンワン」と鳴きます」と表示するコードを書いてください。 */ } // メインクラス public class Main { public static void main(String[] args) { /* 【穴埋め問題2】 ここにAnimalクラスのインスタンスgenericAnimalを作成し、soundメソッドを呼び出すコードを書いてください。 出力は「動物は音を出します」となります。 */ /* 【穴埋め問題3】 ここにDogクラスのインスタンスmyDogを作成し、soundメソッドを呼び出すコードを書いてください。 出力は「犬は「ワンワン」と鳴きます」となります。 */ } }
このヒントを見てもまだ回答を導き出すのが難しいと感じる場合は、先に正解のコードと解説を見て内容を理解するようにしましょう。
練習問題の解答と解説
この問題の正解コードとその解説は以下の通りです。
クリックして開いて確認してください。
- 正解コード
-
// 親クラス:動物(Animal) class Animal { // 動物の鳴き声を表示するメソッド public void sound() { System.out.println("動物は音を出します"); } } // 子クラス:犬(Dog) - Animalクラスを継承 class Dog extends Animal { // soundメソッドをオーバーライドして、犬特有の鳴き声を表示する @Override public void sound() { System.out.println("犬は「ワンワン」と鳴きます"); } } // メインクラス public class Main { public static void main(String[] args) { // Animalクラスのインスタンスを作成してsoundメソッドを呼び出す Animal genericAnimal = new Animal(); genericAnimal.sound(); // 出力:動物は音を出します // Dogクラスのインスタンスを作成してsoundメソッドを呼び出す Dog myDog = new Dog(); myDog.sound(); // 出力:犬は「ワンワン」と鳴きます } }
- 正解コードの解説
-
コードをブロックごとに分割して解説します。
親クラス:Animal
class Animal { // 動物の鳴き声を表示するメソッド public void sound() { System.out.println("動物は音を出します"); } }
Animal
クラスは基本的な動物の機能を持つ親クラスです。sound
メソッドには「動物は音を出します」と表示するコードが含まれており、動物全般の鳴き声を表現しています。子クラス:Dog
class Dog extends Animal { @Override public void sound() { System.out.println("犬は「ワンワン」と鳴きます"); } }
Dog
クラスはAnimal
クラスを継承しており、動物の一種である「犬」を表しています。メソッドのオーバーライド
@Override
は、Animal
クラスのsound
メソッドをDog
クラス独自の実装に書き換えていることを示しています。オーバーライド(上書き)によって、
Dog
クラスのsound
メソッドを呼び出すと「犬は「ワンワン」と鳴きます」と表示され、犬特有の鳴き声が表現されるようになります。オーバーライドすることで、親クラスから継承したメソッドを子クラスの要件に合わせてカスタマイズすることができます。
メインクラス:Main
public class Main { public static void main(String[] args) { Animal genericAnimal = new Animal(); genericAnimal.sound(); // 出力:動物は音を出します Dog myDog = new Dog(); myDog.sound(); // 出力:犬は「ワンワン」と鳴きます } }
Main
クラスにはmain
メソッドがあり、プログラムの実行がここから始まります。このメソッドの役割は
Animal
クラスとDog
クラスのインスタンスを作成し、それぞれのsound
メソッドを呼び出すことです。インスタンスの生成とメソッドの呼び出し
genericAnimal
はAnimal
クラスのインスタンスで、sound
メソッドを呼び出すと「動物は音を出します」が表示されます。myDog
はDog
クラスのインスタンスで、sound
メソッドを呼び出すと「犬は「ワンワン」と鳴きます」が表示され、Dog
クラスでオーバーライドされたメソッドが適用されます。
まとめ
このコードではJavaの基本的なオブジェクト指向の概念である「継承」と「メソッドのオーバーライド」について学びました。
親クラスと子クラスの関係を通じて、通の動作を持たせながらも、それぞれのクラスの特性に応じた動作を実現できることがわかります。
Javaのオブジェクト指向を使って柔軟なプログラムを作成するための第一歩として、このコードを理解し、実際に変更を加えてみましょう。