メソッドのオーバーライド (@Override)
CoddyのJavaジャーニー「オブジェクト指向プログラミング」セクションの一部 — レッスン 22/87。
メソッドのオーバーライドは、サブクラスが親クラスで既に定義されているメソッドに対して、独自の定義を提供できるようにするものです。これにより、子クラスは継承した動作を特定のニーズに合わせてカスタマイズすることができます。
メソッドをオーバーライドすると、そのサブクラスのオブジェクトに対して、サブクラスのバージョンが親クラスのバージョンを完全に置き換えます。メソッドは、親メソッドと同じ名前、戻り値の型、およびパラメータを持つ必要があります。
public class Animal {
public void makeSound() {
System.out.println("Some generic sound");
}
}
public class Dog extends Animal {
@Override
public void makeSound() {
System.out.println("Woof!");
}
}
public class Cat extends Animal {
@Override
public void makeSound() {
System.out.println("Meow!");
}
}@Overrideアノテーションは、親メソッドをオーバーライドする意図があることをコンパイラに伝えます。これは任意ですが、メソッド名のスペルを間違えたり、誤ったパラメータを使用したりした場合にコンパイラがエラーをキャッチできるため、強く推奨されます。
@Override
public void makeSound() { } // 正解 - コンパイラがこれを検証します
public void makesound() { } // タイポ!オーバーライドする代わりに新しいメソッドを作成しますオーバーライドされたメソッドを呼び出すと、Javaは実際のオブジェクト型に属するバージョンを実行します:
Dog dog = new Dog();
dog.makeSound(); // 出力: Woof!
Cat cat = new Cat();
cat.makeSound(); // 出力: Meow!前のレッスンで学んだように、新しいコードと一緒に親の振る舞いも含めたい場合は、オーバーライドされたメソッドの中で super.methodName() を使用できることを思い出してください。
チャレンジ
簡単サブクラスが親クラスのメソッドをオーバーライドして、独自の特化した動作を提供する方法を示す通知システムを構築しましょう。@Override アノテーションがどのようにミスの発見に役立つか、また各サブクラスが継承されたメソッドをどのようにカスタマイズできるかを確認します。
コードを整理するために、3つのファイルを作成します:
Notification.java: 汎用的な通知を表す親クラスを作成します。以下の内容を含める必要があります:message(String) 用のプライベートフィールド- メッセージを受け取るコンストラクタ
- メッセージを返すメソッド
getMessage() "Sending notification: " + messageを出力するメソッドsend()
EmailNotification.java: Notification を継承し、メールによる通知送信方法をカスタマイズするサブクラスを作成します:recipientメールアドレス (String) 用のプライベートフィールド- メッセージと受信者の両方を受け取り、親クラスの部分に
super(message)を使用するコンストラクタ @Overrideアノテーションを使用してsend()メソッドをオーバーライドし、"Emailing " + recipient + ": " + getMessage()を出力するようにします
Main.java: 同じメソッド名がオブジェクトの型に応じてどのように異なる動作をするかを実演します。メッセージとメールアドレスの2つの入力を受け取ります。同じメッセージを使用して通常の Notification と EmailNotification の両方を作成し、それぞれでsend()を呼び出して出力の違いを確認してください。
入力として、メッセージ (String) と受信者のメールアドレス (String) の2つを受け取ります。
出力には、まず親クラスの send() メソッドからの行、次に EmailNotification でオーバーライドされたバージョンからの行の2行が表示されるはずです。これは、メソッドのオーバーライドによって、サブクラスが継承した動作を独自の実装に置き換えられることを示しています。
チートシート
メソッドのオーバーライドにより、サブクラスは親クラスですでに定義されているメソッドに対して独自の定義を提供できます。オーバーライドされるメソッドは、親メソッドと同じ名前、戻り値の型、およびパラメータを持つ必要があります。
public class Animal {
public void makeSound() {
System.out.println("Some generic sound");
}
}
public class Dog extends Animal {
@Override
public void makeSound() {
System.out.println("Woof!");
}
}@Override アノテーションは任意ですが、強く推奨されます。これは、親メソッドをオーバーライドする意図をコンパイラに伝え、メソッド名のスペルミスや不適切なパラメータなどのエラーを検出するのに役立ちます:
@Override
public void makeSound() { } // 正解 - コンパイラがこれを検証します
public void makesound() { } // タイポ!オーバーライドする代わりに新しいメソッドを作成しますオーバーライドされたメソッドを呼び出す際、Javaは実際のオブジェクト型に属するバージョンを実行します:
Dog dog = new Dog();
dog.makeSound(); // 出力: Woof!
Cat cat = new Cat();
cat.makeSound(); // 出力: Meow!オーバーライドされたメソッド内で super.methodName() を使用すると、新しいコードとともに親の振る舞いを含めることができます。
自分で試してみよう
import java.util.Scanner;
class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// 入力を読み込む
String message = scanner.nextLine();
String recipient = scanner.nextLine();
// TODO: message を使用して Notification オブジェクトを作成する
// TODO: message と recipient を使用して EmailNotification オブジェクトを作成する
// TODO: Notification オブジェクトの send() を呼び出す
// TODO: EmailNotification オブジェクトの send() を呼び出す
}
}
このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。
オブジェクト指向プログラミングのすべてのレッスン
4継承
継承の基本 (extends)super キーワードメソッドのオーバーライド (@Override)コンストラクタチェーンObject クラス単一継承と多段階継承なぜ多重継承ができないのかまとめ:従業員の階層構造