Javaとオブジェクト指向 オーバーライド(4-10)

記事上広告

Javaには継承に関連する機能で、オーバーライドという機能があります。オーバーロードと用語が似ているので混同しないように気を付けましょう。

オーバーライドとは

オーバーライドは継承や実装を行った際に、サブクラス(実装クラス)側でスーパークラスと同じ名前のメソッドを再定義(上書き)する機能です。
※実装についてはインターフェイスの項目で説明します。

スーパークラスとサブクラスで同じ名前のメソッドが定義することで、サブクラス特有の追加処理を記述することができます。

上の図解では処理Aが処理Bに上書きされます。
(処理Aがオーバーライドされる側、処理Bがオーバーライドする側となります)

オーバーライドのルール

オーバーライドするメソッドはオーバーライドされるメソッドと「戻り値の型」「メソッド名」「引数の型や数」が同じである必要があります。

オーバーライドにはほかにもいくつかルールがありますが、その他のルールは別の記事で紹介します。

例えば以下のようなメソッドを親クラスで定義します。

次に上のクラスを継承し、メソッドをオーバーライドします。

オーバーライドする側のメソッドでは、配列を並び替えるだけでなく、表示処理も追加されています。

しかし、オーバーライドしたつもりでも、以下のようなメソッドを定義した場合はオーバーライドにはなりません。(エラーも起こりません)

上のメソッドは親クラスのメソッドとは「引数の型」が異なる為、オーバーロード扱いになります。

オーバーライド サンプルプログラム

以下のプログラムを「Autobike.java」「Number34.java」という名前でworkフォルダ内に保存します。
※すでにAutobike.javaVehicle.javaを作成済みの場合は、Autobike.javaの追加のメソッド部分を記述してください。Vehicle.java継承の記事にあります。

保存が完了したら、コマンドプロンプトを起動し、Number34.javaをコンパイルおよび実行をしてみましょう。

実行例

C:\work>javac Number34.java

Autobike.java:16: エラー: handleはVehicleでprivateアクセスされます
if(c >= -45 && c <= 45) handle = c;
^
エラー1個

※実行例はコンパイルの例を表示しています。

サンプルプログラムの修正

Autobike.javaVehicle.javaを継承しており、handleOperation()とdisplay()のオーバーライドを行っています。しかし、handleOperation()メソッド内で利用しているフィールドはprivate宣言されており、継承関係にあってもフィールドを利用することができません。

Vehicle(親)クラスにフィールドにアクセスするためのメソッドを追加する方法もありますが、今回はsuperを利用した記述に変更します。

また、dipslay()内も親クラスのdisplay()の内容を表示できるように変更します。

具体的には以下のようにAutobike.javaを変更します。
※変更の必要がないフィールドやメソッドは割愛しています

保存が完了したら、コマンドプロンプトを起動し、Number34.javaをコンパイルおよび実行をしてみましょう。

実行例

C:\work>javac Number34.java

C:\work>java Number34
オートバイを運転中。
ただ今直進中です。
スピードは10km/hです。

※実行例はコンパイルおよび実行までの例を表示しています。

オーバーライドとsuper

オーバーライドされたメソッドはサブクラスでも利用ができます。その際はsuperキーワードと併用してメソッドを呼び出します。

スーパークラスのメソッドを利用 super.メソッド名(引数) ;
記述例 super.display() ;

superキーワードを利用することで、スーパークラスのメソッドを利用することを明示し、自クラスのメソッドと区別をつけることで、オーバーライドされる側のメソッドを呼び出すことができます。

しかし、継承関係はスーパークラスとサブクラスで成り立つため、スーパークラスが継承しているクラスのメソッドは利用できません。(以下の図解参照)

オーバーライド 復習問題

問題
  • void method(int a, int b)のメソッドをオーバーライドしているメソッドを選んでください。
  • オーバーライドの説明として正しいものを選んでください。
  • オーバーライドの説明として正しいものを選んでください。
  • お疲れ様でした。
解答群
    1. void method(int x, int y)
    2. void method(int x)
    3. void method(double x, double y)
    4. int method(int a, int b)
    1. 引数で利用する型が異なっていてもオーバーライドできる
    2. 引数で利用する変数名が異なっていてもオーバーライドできる
    3. 引数で利用する型の並びが異なっていてもオーバーライドできる
    4. 戻り値の型が異なっていてもオーバーライドできる
    1. super()でスーパークラスのメソッドにアクセスできる
    2. override()でスーパークラスのメソッドにアクセスできる
    3. super.メソッド名()でスーパークラスのメソッドにアクセスできる
    4. this()でスーパークラスのメソッドにアクセスできる

まとめ

  • オーバーライドはサブクラス側でスーパークラスのメソッドを再定義することができる
  • オーバーライドはスーパークラスのメソッドと「メソッド名」「戻り値の型」「引数」を同一にする必要がある
  • superキーワードを利用することでオーバーライドされる側のメソッドをサブクラス側で利用が可能
スポンサーリンク
レクタングル