【Java入門】オーバーライド(Override)の使い方

こんにちは!フリーランスの長野です。

オーバーライドって使っていますか?すでに存在するクラスのあるメソッドを変更して使いたい場合などに便利ですよね。変更したいメソッドだけを記述し直すだけで、メンバ変数や他のメソッドをあらためて記述する必要がないのが便利です。

この記事では、オーバーライドについて

  • オーバーライドとは
  • オーバーライドの使い方
  • superの使い方
  • 使用する上での決まり事

など基本的な内容から、応用的な内容についても解説していきます。今回はオーバーライドについて、使い方をわかりやすく解説します!

なお、Javaの記事については、こちらにまとめています。

目次

オーバーライドとは

オーバーライドとはクラスを継承する時に、スーパークラスのメソッドをサブクラスにおいて同じメソッド名で定義し直すことを言います。オーバーライドする際には、メソッド名を同じにする必要があるのに加えて、メソッドの引数は同じ数、同じ順番にする必要があります。

ちなみに、スーパークラスとは継承され親となるクラスのことで、サブクラスとは継承したクラスのことです。また「super」句を使うと、オーバーライドした場合でもスーパークラスで定義したメソッドを変更せずにそのまま使用することも可能です。

使用するメリット

オーバーライドは継承したサブクラスのメソッドで使用します。まずそもそも継承するメリットですが一言で言うと、再利用できて、書く記述量を減らすことができるという点です。変更が必要な場合も、変更する箇所も少なくできます。

オーバーライドのおかげで、メソッドの変更が必要な場合に変更箇所が少なくて済みます。クラスのメンバ変数などはそのまま再利用して、変更したいメソッドだけを再定義することができます。

「再利用しつつも、変えたいところは自由に変えられる」というポリモーフィズム(多様性)の思想を実現しています。スーパークラスを継承するメリットについては、こちらで詳しく解説していますのでぜひ参考にしてください。

オーバーロードとの違い

似たような用語でオーバーロードがあります。よく間違われるので、簡単に説明しておきます。

オーバーロードとは同じメソッド名で、引数の数や順番が違うメソッドを定義することです。今回解説しているオーバーライドは継承したサブクラスで同じメソッド名で、引数の数や順番が同じメソッドを再定義することでした。

間違えないようにしましょう!

オーバーライドの使い方

オーバーライドの使い方をサンプルコードを使いながらみていきましょう。

// スーパークラス
class ClassSuper {
    protected int i1 = 3;
    protected int i2 = 5;
 
    public void calc(){
        System.out.println("i1 + i2 = " + (i1 + i2));
    }
}
//サブクラス
class ClassSub extends ClassSuper{
    @Override
    public void calc(){
        System.out.println("i1 * i2 = " + (i1 * i2)); // 処理を変更
    }
}
 
public class Main {
 
    public static void main(String[] args) {
        ClassSub cs = new ClassSub();
        cs.calc();
    }
 
}

実行結果:

i1 * i2 = 15

この例ではClassSubクラスがClassSuperクラスを継承しています。スーパークラスであるClassSuperクラスのcalcメソッドをClassSubクラスでオーバーライドして処理を変更しています。

なお、サブクラスでcalcメソッドを再定義する前に「@Override」と記述しています。コメントアウトされていますが、これはアノテーションと呼ばれています。

アノテーションでは後ほど解説します。

superの使い方

「super」句を使うことで、サブクラスでオーバーライドしていてもスーパークラスのメソッドをそのまま使うことができます。

実際にサンプルコードで確認しましょう。

// スーパークラス
class ClassSuper {
    protected int i1;
    protected int i2;
 
    public ClassSuper(int i1, int i2){
        this.i1 = i1;
        this.i2 = i2;
    }
 
    public void calc(){
        System.out.println("i1 + i2 = " + (i1 + i2));
    }
}
// サブクラス
class ClassSub extends ClassSuper{
    public ClassSub(int i1, int i2) {
        super(i1, i2);
    }
 
    @Override
    public void calc(){
        System.out.println("i1 * i2 = " + (i1 * i2)); // 処理を変更
        super.calc(); // スーパークラスと同じ処理
    }
}
 
public class Main {
 
    public static void main(String[] args) {
        ClassSub cs = new ClassSub(3, 5);
        cs.calc();
    }
 
}

実行結果:

i1 * i2 = 15
i1 + i2 = 8

この例でもClassSubクラスがClassSuperクラスを継承しています。スーパークラスであるClassSuperクラスのcalcメソッドをClassSubクラスでオーバーライドして処理を変更しています。その後に「super」句を使ってcalcメソッドを呼び出していますが、その結果はスーパークラスであるClassSuperクラスのcalcメソッドのそれと一致します。

このように「super」句を使うことで、サブクラスでオーバーライドしていてもスーパークラスのメソッドをそのまま使うことができます。また、この例ではコンストラクタを使用して値を代入しています。

スーパークラスのコンストラクタはサブクラスでも記述する必要がありますが、「super」句を使うことで簡潔に記述することができ、そのまま使うことができます。

superについては、こちらで詳しく解説していますのでぜひ参考にして下さい。

使用する上での決まり事

スーパークラスを再利用しつつも、変えたいメソッドは自由に変えられる」ので、便利なオーバーライドですが、使用する上で守らなければならない決まり事がいくつかあります。詳しく説明していきます。

戻り値の型と引数について

前にも述べていますが、オーバーライドはクラス名が同じで、引数の数や順番も同じにする必要があります。また、メソッドの戻り値の型も同じにする必要があります。

@Override(アノテーション)について

ご紹介しているサンプルコードでもオーバーライドで再定義するメソッドの前に「@Override」と記述しています。コメントアウトされていますが、これをアノテーションと呼びます。

アノテーションとは、オーバーライドすることを宣言するために記述します。これを記述することで、もしスーパークラスに同名のメソッドがなければコンパイラがエラーメッセージを出しますので、付けておくことをオススメします。

なお、記述しなくても問題はありません。アノテーションについては、こちらで詳しく解説していますのでぜひ参考にして下さい。

static修飾子について

staticメソッドはクラス固有のメソッドであるため、オーバーライドすることはできません。注意しましょう。

なおstaticメソッドについては、こちらで詳しく解説していますのでぜひ参考にして下さい。

private修飾子について

サブクラスでオーバーライドしたメソッドは、スーパークラス側のメソッドに指定されるアクセスレベルより制限の厳しいアクセスレベルを付与することができません。例えばスーパークラス側のメソッドにprotectedで指定している場合、サブクラスではpreivateで指定することはできません。

ご注意ください!

アクセス修飾子のアクセスレベルについては、こちらで詳しく解説していますのでぜひ参考にして下さい。

abstract修飾子について

スーパークラス側のメソッドにabstract修飾子が付与されている場合は、サブクラスでは必ずオーバーライドする必要があります。もしオーバーライドしない場合は、そのサブクラス全体がabstractクラスになります。

abstract修飾子の使い方については、こちらで詳しく解説していますのでぜひ参考にして下さい。

final修飾子について

スーパークラス側のメソッドにfinal修飾子が付与されている場合は、サブクラスでそのメソッドのオーバーライドはできません。final修飾子の使い方については、こちらで詳しく解説していますのでぜひ参考にして下さい。

throwsでの例外クラスの指定について

スーパークラス側のメソッドでthrowsを使って例外を投げる場合は、サブクラスでオーバーライドするメソッドは注意が必要です。オーバーライドするメソッドで、スーパークラス側のメソッドのthrowsで指定した例外クラス以外を指定することはできません。

throwsの使い方については、こちらで詳しく解説していますのでぜひ参考にして下さい。

まとめ

ここでは、オーバーライドの使い方やsuperの使い方について説明しました。

継承してオーバーライドを使うことで、後々処理を変更することができるので便利です。また「super」句を使うことで、変更せずにそのまま使うこともできます。ただし、使用する上での決まり事もありますので、それを守るように注意して下さい。

使いこなすことができるように、この記事を何度も参考にして下さいね!

この記事を書いた人

熊本在住のフリープログラマ兼ライターです。C/C++/C#、Java、Python、HTML/CSS、PHPを使ってプログラミングをしています。専門は画像処理で最近は機械学習、ディープラーニングにはまっています。幅広くやってきた経験を活かしてポイントをわかりやすくお伝えしようと思います。
お問合せはこちらでも受け付けています。
info@sss-lab.com

目次