Java のメソッドのオーバーライド(@Override を使って親クラスを上書き)を初心者向けにやさしく解説
新人
「Javaで親クラスの動きを変えたいときって、どうやってやるんですか?」
先輩
「それなら@Overrideを使うといいよ。親クラスのメソッドを子クラスで上書きできるんだ。」
新人
「上書きっていうのは、もともとの動きを別のものに変えるってことですか?」
先輩
「そのとおり。じゃあ、Javaのオーバーライドについて一緒に見てみようか!」
1. オーバーライドとは?(基本の意味と考え方)
Javaのオーバーライドとは、親クラスにあるメソッドを、子クラスで上書きして、自分用の動きに変えることです。
たとえば、Animalという親クラスに「鳴く」動きがあるとします。これをDogという子クラスで「ワンワン」と鳴かせたいとき、オーバーライドを使えば実現できます。
public class Animal {
void makeSound() {
System.out.println("何かの動物が鳴きます。");
}
}
public class Dog extends Animal {
@Override
void makeSound() {
System.out.println("ワンワン!");
}
}
Dogクラスでは、親のmakeSound()を@Overrideで上書きして、「ワンワン!」と表示されるようにしています。
このように、Javaのオーバーライドは、子クラスで自分専用の動作を作りたいときに使います。
2. なぜオーバーライドが必要なのか?(現実の例で考える)
現実の世界でも、「同じ名前でも使い方が違うもの」はたくさんあります。たとえば、「鳴く」という行動は、犬なら「ワンワン」、猫なら「ニャー」となりますよね。
Javaでも、同じメソッド名を使いながら、それぞれのクラスで違う動作をさせたいときがあります。そこで活躍するのがオーバーライドです。
次の例を見てください。Animalという親クラスにmakeSound()メソッドがあり、それをDogとCatで上書きしています。
public class Animal {
void makeSound() {
System.out.println("動物の鳴き声");
}
}
public class Dog extends Animal {
@Override
void makeSound() {
System.out.println("ワンワン!");
}
}
public class Cat extends Animal {
@Override
void makeSound() {
System.out.println("ニャー!");
}
}
このようにすれば、makeSound()を呼び出すだけで、それぞれの動物に合った音を出せます。
public class Main {
public static void main(String[] args) {
Dog dog = new Dog();
Cat cat = new Cat();
dog.makeSound(); // ワンワン!
cat.makeSound(); // ニャー!
}
}
ワンワン!
ニャー!
このように、親クラスの機能を引き継ぎながら、自分なりの動きに変えることができるのが、Javaのオーバーライドの最大のメリットです。
そして、このオーバーライドのときに@Overrideを書くことで、Javaが「これは親のメソッドを上書きしてますね」と確認してくれるので、書き間違いを防げるという利点もあります。
3. Javaでオーバーライドを書く基本の書き方(@Overrideの使い方)
Javaでオーバーライドを書くときは、親クラスとまったく同じ名前と形のメソッドを子クラスにもう一度書きます。その上で、@Overrideというアノテーションをその上に書きます。
この@Overrideは「このメソッドは親クラスのメソッドを上書きしていますよ」という目印のようなものです。
たとえば、次のように使います。
public class Animal {
void makeSound() {
System.out.println("何かの動物が鳴いています。");
}
}
public class Dog extends Animal {
@Override
void makeSound() {
System.out.println("ワンワン!");
}
}
このように@Overrideをつけておけば、メソッド名や引数を間違えたときにエラーを出してくれるので、書き間違いにすぐ気づけます。
特に初心者は、メソッド名の小文字・大文字を間違えたり、引数を忘れたりしやすいので、@Overrideをつけるのがとてもおすすめです。
4. オーバーライドされたメソッドの動き方(実行結果で確認)
Javaのオーバーライドが正しく動いているかどうかは、実際にプログラムを動かしてみるのが一番よく分かります。
ここでは、親クラスのメソッドを子クラスで上書きした例を使って、出力結果がどう変わるかを確認してみましょう。
public class Animal {
void speak() {
System.out.println("動物が何かを話します。");
}
}
public class Bird extends Animal {
@Override
void speak() {
System.out.println("チュンチュン!");
}
}
public class Main {
public static void main(String[] args) {
Animal a = new Animal();
a.speak(); // 親クラスのメソッド
Bird b = new Bird();
b.speak(); // 子クラスで上書きされたメソッド
}
}
動物が何かを話します。
チュンチュン!
親クラスのspeak()を呼ぶと「動物が何かを話します。」と表示され、子クラスのspeak()を呼ぶと「チュンチュン!」と表示されます。
このように、同じメソッド名でも、子クラスの中身が優先されて実行されるのが、オーバーライドの特徴です。
5. オーバーライドしないとどうなる?(書き間違いを防ぐ理由)
Javaで@Overrideを書かずにオーバーライドしようとすると、うっかり書き間違いに気づけないことがあります。
たとえば、親クラスのメソッド名を「sayHello」にしていたのに、子クラスで「sayhello」」と書いてしまったとしましょう。大文字と小文字が違います。
public class Person {
void sayHello() {
System.out.println("こんにちは!");
}
}
public class Student extends Person {
// @Override を書いていない
void sayhello() { // これは別のメソッドと認識されてしまう
System.out.println("やあ!");
}
}
この場合、Javaはsayhello()をsayHello()の上書きだと認識できず、まったく別のメソッドとして扱ってしまいます。
もし@Overrideをつけていれば、このような書き間違いがあっても「親にそんなメソッドないよ」と教えてくれるので、すぐに直すことができます。
public class Student extends Person {
@Override
void sayhello() { // ここでコンパイルエラーになる!
System.out.println("やあ!");
}
}
このように、@Overrideは安心してオーバーライドを書くためのチェック機能のようなものです。
初心者のうちは、間違いを見逃しやすいので、Javaでオーバーライドを書くときは必ず@Overrideをつける習慣をつけておくのが安心です。
6. 親クラスと子クラスで同じ名前のメソッドがあるとどうなる?
Javaでは、親クラスと子クラスの両方に同じ名前のメソッドがある場合、子クラスのメソッドが優先されて実行されます。これは、子クラスが親から継承したメソッドを「上書き」しているからです。
実際の例で確認してみましょう。
public class Animal {
void info() {
System.out.println("これは動物です。");
}
}
public class Dog extends Animal {
@Override
void info() {
System.out.println("これは犬です。");
}
}
public class Main {
public static void main(String[] args) {
Animal a = new Animal();
a.info(); // 親クラスのメソッド
Dog d = new Dog();
d.info(); // 子クラスのメソッド
}
}
これは動物です。
これは犬です。
このように、同じメソッド名でも、オーバーライドされていれば、子クラスの動きに変わります。これはJavaの特徴のひとつで、動きの切り替えが自然にできる仕組みです。
7. オーバーライドの注意点(引数の違い・スペルミスなど)
Javaのオーバーライドには、いくつかの注意点があります。特に初心者がよくつまずくのは、メソッド名のスペルミスや、引数の数や型が違うことによる失敗です。
たとえば、親クラスで次のようなメソッドがあるとします。
public class Person {
void greet(String name) {
System.out.println("こんにちは、" + name + "さん!");
}
}
このとき、子クラスで次のように書いたとします。
public class Student extends Person {
// greetの引数なしバージョンを定義(オーバーライドではない)
void greet() {
System.out.println("やあ!");
}
}
これは実はオーバーライドではありません。引数が違うため、まったく別のメソッドとして扱われてしまいます。
このようなときも@Overrideを書いておけば、「これはオーバーライドじゃないよ」と教えてくれます。
public class Student extends Person {
@Override
void greet() { // エラーになる
System.out.println("やあ!");
}
}
エラーになることで、「あ、親のメソッドと違っていたんだな」とすぐに気づけます。
また、スペルミスも要注意です。たとえば、greetと書くところをgreteと書いてしまうと、これも別のメソッドになります。こうした間違いも、@Overrideを使うことで防げます。
8. 初心者がオーバーライドを正しく使うコツ(アドバイス)
Javaのオーバーライドを正しく使うためには、いくつかのポイントを押さえておくと安心です。特に初心者にとって大切なのは、シンプルに考えることと、正しい書き方の習慣を身につけることです。
まずひとつ目は、@Overrideを必ず書くことです。これを忘れずにつけておけば、ミスをすぐに見つけることができます。Pleiadesでは、エラーが赤い波線などで表示されるので、すぐに直せます。
二つ目は、親クラスのメソッドの形(引数や戻り値)をしっかり確認することです。上書きしたいなら、同じ名前・同じ引数・同じ戻り値で書く必要があります。
三つ目は、実際に手を動かしてオーバーライドを書いてみることです。たとえば次のような小さなコードを自分で作ってみると理解が深まります。
public class Greeting {
void sayHello() {
System.out.println("こんにちは!");
}
}
public class CasualGreeting extends Greeting {
@Override
void sayHello() {
System.out.println("やっほー!");
}
}
public class Main {
public static void main(String[] args) {
Greeting g1 = new Greeting();
g1.sayHello(); // こんにちは!
CasualGreeting g2 = new CasualGreeting();
g2.sayHello(); // やっほー!
}
}
こんにちは!
やっほー!
このような短いプログラムを何度も試していくと、Javaのオーバーライドに自然と慣れていきます。
親クラスの動きを@Overrideで自分なりに書き換えることで、子クラスの振る舞いを自由にコントロールできるようになります。
そしてそれが、Javaプログラミングの大きな力となります。