この記事で学べる知識:メソッドのオーバーライド
この記事の練習問題で使用する知識:
基礎構文、制御構造、メソッド、コレクション(レッスン1~4)、クラスの定義と使用、コンストラクタ、カプセル化、クラスメンバとインスタンスメンバ、クラスの継承、メソッドのオーバーライド、抽象クラス、インターフェース
<<前のページ | テキストTop |
次のページ>> |
JAVAの「メソッドのオーバーライド」とは
この章では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
で宣言されたメソッドはオーバーライドできないため注意が必要です。
また例外についてもルールがあります。
親クラスのメソッドが特定の例外をスローする場合、子クラスのオーバーライドメソッドは同じ例外か、それよりも狭い範囲の例外をスローする必要があります。
まとめ
メソッドのオーバーライドは、クラスの継承を活用してクラスごとの動作を実装する重要な技術です。
オーバーライドを使うことで、親クラスのメソッドを子クラスで独自に実装し、より柔軟で再利用性の高いコードを作成できます。
クラスの継承との関係やルールを正しく理解し、効果的に活用していきましょう。
練習問題5-6:動物の鳴き声を表示するプログラムを作ろう
動物の鳴き声を表示するプログラムを作成しましょう。
このプログラムでは動物の基本的な鳴き声を表示する「動物クラス」と、それを継承して「犬クラス」を作成します。
犬クラスではメソッドのオーバーライドを使って、犬が鳴くときの特有の鳴き声を表示します。
この問題の要件
以下の要件に従ってコードを完成させてください。
Animal
クラスを作成し、sound
メソッドを定義すること。sound
メソッドは「動物は音を出します」と表示すること。
Animal
クラスを継承したDog
クラスを作成し、sound
メソッドをオーバーライドすること。- オーバーライドした
sound
メソッドでは「犬は「ワンワン」と鳴きます」と表示すること。
- オーバーライドした
Main
クラス内で以下の処理を行うこと。Animal
クラスのインスタンスを作成し、sound
メソッドを呼び出すこと。Dog
クラスのインスタンスを作成し、sound
メソッドを呼び出すこと。
ただし、以下のような実行結果となるコードを書くこと。
*****↓↓正解コードの実行結果の例↓↓*****
動物は音を出します 犬は「ワンワン」と鳴きます
この問題を解くヒント
1からコードを組み立てることが難しい場合は、以下のヒントを開いて参考にしましょう。
正解のコードは上から順に以下のような構成となっています。
(※下記の□はコード内のインデントを表しています)
1:Animalクラスの定義
□ soundメソッドの定義
□ □ 「動物は音を出します」と出力する
2:Dogクラスの定義(Animalクラスを継承)
□ soundメソッドのオーバーライド
□ □ 「犬は「ワンワン」と鳴きます」と出力する
3:Mainクラスの定義
□ mainメソッドの定義
□ □ AnimalクラスのインスタンスgenericAnimalを作成
□ □ genericAnimalのsoundメソッドを呼び出す
□ □ DogクラスのインスタンスmyDogを作成
□ □ myDogのsoundメソッドを呼び出す
以下のコードをコピーし、コメントに従ってコードを完成させて下さい。
// 親クラス:動物(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(); // 出力:犬は「ワンワン」と鳴きます } }
正解コードの解説
正解コードの解説を以下に示します。
この解説を通して、Javaの継承やメソッドのオーバーライドの基礎を学びましょう。
親クラス: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のオブジェクト指向を使って柔軟なプログラムを作成するための第一歩として、このコードを理解し、実際に変更を加えてみましょう。
<<前のページ |
テキストTop |
次のページ>> |
この記事への質問・コメント
この記事を作成するにあたりAIを活用しています。
問題ないことは確認していますが、もし間違いや表現の違和感などありましたら、ご指摘頂けると大変助かります。