Java入門 STEP13|オーバーライドを学ぼう

karin@taishi@felmia

STEP12では、親クラスの機能を子クラスに引き継ぐ「継承」について学びました。

継承すると、親クラスが持っているメソッドを子クラスでも使うことができます。

ただし、子クラスによっては、親クラスと同じ処理ではなく、そのクラスに合った処理に変えたい場合があります。

そこで使うのが「オーバーライド」です。

オーバーライドとは?

まずは、STEP12でも使ったAnimalクラスを例に考えます。

public class Animal {

    public void makeSound() {
        System.out.println("鳴きます");
    }
}

Animalクラスには、makeSound()というメソッドがあります。

このクラスをDogクラスが継承すれば、DogでもmakeSound()を使うことができます。

しかし、犬であれば「鳴きます」ではなく、

ワン!

と表示したいところです。

このように、親クラスから継承したメソッドを、子クラスに合わせた処理に書き換えることをオーバーライドといいます。

オーバーライドとは?

親クラスから継承したメソッドを、子クラス側で同じメソッド名・同じ引数で定義し直す仕組みです。

ルミィ
ルミィ

親クラスのメソッドをそのまま使うだけじゃなくて、子クラスに合わせて変えることもできるんだね♪

オーバーライドの書き方

Animalを継承したDogクラスで、makeSound()をオーバーライドします。

public class Dog extends Animal {

    @Override
    public void makeSound() {
        System.out.println("ワン!");
    }
}

親クラスのAnimalにも、

public void makeSound()

というメソッドがあります。

Dogクラスで同じmakeSound()を定義することで、Dogではこちらの処理が使われるようになります。

Mainクラスから呼び出します。

public class Main {

    public static void main(String[] args) {

        Dog dog = new Dog();

        dog.makeSound();
    }
}

実行結果

ワン!

親クラスに書かれていた「鳴きます」ではなく、Dogクラスに書いた「ワン!」が表示されました。

これがオーバーライドです。

@Overrideとは?

先ほどのDogクラスでは、makeSound()の上に、

@Override

と書いています。

@Overrideはアノテーションと呼ばれるものです。

ここでは、

「このメソッドは、親クラスのメソッドをオーバーライドしています」

とJavaに伝えるもの、と考えておけば大丈夫です。

@Overrideを付ける理由

@Overrideを付けておくと、メソッド名や引数などを間違えたときに、正しくオーバーライドできていないことをコンパイルエラーで確認できます。

オーバーライドするときは、基本的に付けておきましょう。

例えば、makeSound()を間違えて次のように書いたとします。

@Override
public void makeSounds() {
    System.out.println("ワン!");
}

親クラスにmakeSounds()というメソッドはありません。

@Overrideを付けているため、親クラスのメソッドを正しくオーバーライドできていないことをエラーで確認できます。

ルミィ
ルミィ

名前をちょっと間違えただけでも教えてくれるんだ!
@Overrideを付けておくと安心だね♪

メソッド名だけ同じではダメ

オーバーライドでは、メソッド名だけを同じにすればよいわけではありません。

親クラスが、

public void makeSound() {
    System.out.println("鳴きます");
}

となっている場合、子クラスでは、

@Override
public void makeSound() {
    System.out.println("ワン!");
}

のように定義します。

一方で、

public void makeSound(String sound) {
    System.out.println(sound);
}

とすると、引数が異なっています。

これは親クラスのmakeSound()を書き換えているのではなく、別のメソッドを定義していることになります。

オーバーライドとオーバーロードの違い

ここは名前が似ているため、最初は間違えやすいところです。

以前学んだオーバーロードと、今回のオーバーライドを比べてみます。

オーバーライド

親クラスから継承したメソッドの処理を、子クラス側で変更します。

@Override
public void makeSound()

オーバーロード

同じ名前で、引数の数やデータ型が異なるメソッドを複数定義します。

Student()

Student(String name, int score)

オーバーライド → 継承したメソッドの処理を変える

オーバーロード → 引数の異なる同名のメソッドを作る

名前は似ていますが、使う目的は異なります。

ルミィ
ルミィ

オーバーライドとオーバーロード、名前は似ているけど意味は別なんだね。
ここは間違えないように覚えておこっと♪

子クラスごとに処理を変えられる

今度はDogだけでなく、CatクラスもAnimalから継承します。

public class Cat extends Animal {

    @Override
    public void makeSound() {
        System.out.println("ニャー!");
    }
}

DogとCatは、どちらもAnimalを継承しています。

それぞれのmakeSound()を呼び出します。

public class Main {

    public static void main(String[] args) {

        Dog dog = new Dog();
        Cat cat = new Cat();

        dog.makeSound();
        cat.makeSound();
    }
}

実行結果

ワン!
ニャー!

同じAnimalを継承していても、Dogでは「ワン!」、Catでは「ニャー!」と表示されました。

オーバーライドを使うことで、共通する部分は親クラスから引き継ぎ、必要な処理だけを子クラスごとに変えることができます。

よくある間違い

メソッド名を間違える

親クラスが、

makeSound()

なのに、

makeSounds()

と書くと、別のメソッドになります。

@Overrideを付けていれば、このような間違いをコンパイルエラーで確認できます。

引数を変えてしまう

親クラスが、

makeSound()

なのに、

makeSound(String sound)

とすると、オーバーライドにはなりません。

オーバーライドする場合は、親クラスのメソッドと同じ形になっているかを確認しましょう。

STEP13のまとめ

STEP13のポイント

  • オーバーライドは、親クラスから継承したメソッドの処理を子クラス側で変更する仕組み
  • オーバーライドするときは@Overrideを付ける
  • メソッド名だけでなく、引数なども親クラスのメソッドに合わせる
  • @Overrideを付けることで記述ミスに気づきやすくなる
  • オーバーライドとオーバーロードは別の仕組み
  • 同じ親クラスを継承していても、子クラスごとに違う処理を持たせることができる

最初は、「親クラスから受け継いだメソッドの処理を、子クラス用に変更できる」というところを理解できれば大丈夫です。

ルミィ
ルミィ

STEP13クリア!
同じメソッドでも、子クラスに合わせて処理を変えられるんだね♪

次のSTEPへ

次のSTEPでは、「抽象クラス」について学びます。

ここまで、継承を使って親クラスの機能を引き継ぎ、オーバーライドによって子クラスごとに処理を変える方法を学びました。

ただ、親クラスによっては「共通する部分はまとめたいけれど、このクラスから直接オブジェクトを作る必要はない」という場合があります。

そんなときに使えるのが抽象クラスです。

抽象クラスを使うと、共通する処理を親クラスにまとめながら、子クラス側で実装してほしいメソッドを決めておくこともできます。

→ STEP14「抽象クラスを学ぼう」

学習内容を確認したいときは、Java入門の一覧から各STEPを確認できます。

→ Java入門|初心者が基礎から学べるJava学習ガイド

記事URLをコピーしました