Javaに関する様々な情報をご紹介します。

9オーバーライドとオーバーロード

Javaに関する様々な情報をご紹介します。

オーバーライドとオーバーロード

このページでは、オーバーライドとオーバーロードについて説明を行います。オーバーライドとは、スーパークラスで定義されたメソッドをサブクラスで再定義することを言います。オーバーロードとは、同一クラス内で、メソッド名が同一で引数の型、数、並び順が異なるメソッドを複数定義することを言います。

オーバーライド

オーバーライドとはスーパークラスにおいて定義されているメソッドを、サブクラス内で再定義することを言います。スーパークラスのメソッドを変更することはできないが、サブクラスに特化した機能を付与したい場合に使用します。

オーバーライド

オーバーライドを定義する際には以下の規定があります。

  1. オーバーライドする側はオーバーライドされる側と戻り型、メソッド名、引数型、引数の数が同じでなければなりません。どれか一つでも異なる場合はオーバーライドとは見なされません。
    オーバーライド2
  2. オーバーライドされる側のメソッドに指定されるアクセスレベルより厳しい制限を持つアクセスレベルをオーバーライドする側のメソッドに付与することはできません。例えばオーバーライドされる側のメソッドにprotectedが指定されている場合、オーバーライドする側のメソッドにprivateを指定することはできません。
  3. オーバーライドされる側のメソッドに指定されるthrows節以外の例外をオーバーライドする側のメソッドに指定することはできません。但し、オーバーライドされる側に指定された例外をより限定する例外をオーバーライドする側に指定することはできます。
  4. オーバーライドされる側のメソッドにfinal修飾子が付与されている場合、そのインスタンスメソッドをオーバーライドすることはできません。
  5. オーバーライドされる側のメソッドにabstract修飾子が付与されている場合、そのメソッドはサブクラスで必ずオーバーライドしなければなりません。オーバーライドしない場合はそのサブクラス全体がabstractクラスになります。

オーバーライドの例を以下に記載します。

スーパークラス(ExClass8クラス)

class ExClass8 {
    //オーバーライドされるメソッド
       //引数に指定された値を10倍にするメソッド
    void methodA(int i) {
        int x = i * 10;
        System.out.println(x);
    }
}

サブクラス(SubExClass8クラス)

class SubExClass8 extends ExClass8 {
    //オーバーライドするメソッド
       //引数に指定された値を1,000倍にするメソッド
    @Override
    void methodA(int i) {
        int x = i * 1000;
        System.out.println(x);
    }
}

動的束縛と静的束縛

動的束縛とはメソッドを呼び出す際、呼び出されるメソッドが、呼び出し先のインスタンスの種類により決定されることを言います。静的束縛とは、呼び出されるメソッドがインスタンスの変数の型により決定されることを言います。動的束縛は、プログラムが実行されるまでどのメソッドが呼び出されるかわからないのに対し、静的束縛は、コンパイルする時点で呼び出すメソッドが決定されます。

多くのプログラム言語が静的束縛を実装する中で、動的束縛はJavaの特徴の一つとなっています。以下に例を記載します。

スーパークラス(ExClass9クラス)

class ExClass9 {
    //オーバーライドされるメソッド
       //引数に指定された値を10倍にするメソッド
    void methodA(int i) {
        int x = i * 10;
        System.out.println(x);
    }
}

サブクラス(SubExClass9クラス)

class SubExClass9 extends ExClass9 {
    //オーバーライドするメソッド
       //引数に指定された値を1,000倍にするメソッド
    @Override
    void methodA(int i) {
        int x = i * 1000;
        System.out.println(x);
    }
}

Mainクラス

class Main {
    public static void main(String[] args) {
        ExClass9 ins1 = new ExClass9();
        ExClass9 ins2 = new SubExClass9();
        //ins1には、ExClass9のインスタンスが代入されているため、
             //ExClass9のメソッドが呼び出される
        ins1.methodA(10);
        //変数の型はExClass9であるが、ins2には、SubExClass9のインスタンスが代入されているため、
             //SubExClass9のメソッドが呼び出される
        ins2.methodA(10);
    }
}

オーバーロード

オーバーロードとは同一クラス内でメソッド名が同一で引数の型、数、並び順が異なるメソッドを複数定義することを言います。

例えば、会員登録を行う機能で、名前と国名を登録させたいとします。国名を入力しなかった会員は国名:日本で登録します。この場合、toroku、torokuJAPANというように別のメソッド名を付けるのではなく、おなじ登録機能であるため、同じメソッド名としたい場合があります。

その際、toroku(String name,String country)、toroku(String name)というように同じ名前のメソッドを引数の数を変えて作成します。Javaはメソッドの引数の型、数、並び順が異なる場合、それぞれを異なるメソッドとして扱います。これがオーバーロードの機能です。

オーバーロード

オーバーロードを定義する際には以下の規定があります。

  1. 異なるメソッドと認識される部分は、メソッドの次の個所です。「引数の型」、「引数の数」、「引数の並び順」。
  2. 次の個所が異なっていても異なるメソッドとは認識されません。コンパイルエラーとなります。「戻り型」、「アクセスレベル」、「引数名」、「throws節」。

オーバーロードを行った例

class ExClass11{
    //引数を2つ持つtorokuメソッド
    void toroku(String name, String country) {
        System.out.println("名前は" + name);
        System.out.println("国は" + country);
    }
    //引数を1つ持つtorokuメソッド
    void toroku(String name) {
        System.out.println("名前は" + name);
        System.out.println("国は" + "日本");
    }
    public static void main(String[] args) {
        ExClass11 ins1 = new ExClass11();
        //引数が1つのメソッドが呼び出される
        ins1.toroku("Java太郎");
    }
}

9オーバーライドとオーバーロード