Javaでは、継承したクラスで親クラスのメソッドを上書きする「オーバーライド」と呼ばれる機能が利用出来ます。
本記事では、Javaにおけるオーバーライドの基本的な使い方と特徴についてご紹介していきます。
目次
Javaのオーバーライドとは
Javaのオーバーライドは、親クラスに定義されたメソッドを継承先の子クラスに同一名のメソッドで定義することにより、処理を上書き出来る機能です。
オーバーライドのメリット
オーバーライドを利用するメリットは、再利用可能な処理はそのまま利用しつつ、変更したい部分は上書き出来る点にあります。
名前の異なる似通った処理のメソッドを作成すると、管理が難しくなるため、オーバーライドを活用してコードの最適化を意識することが大切です。
オーバーロードとの違い
Javaには、オーバーライドに似た名前で「オーバーロード」と呼ばれる機能が提供されています。
オーバーロードは、名前が同じで引数の数やデータ型が異なるメソッドを定義出来ます。
オーバーライドは上述したように継承したクラスの処理を上書きするのに対し、オーバーロードは同一クラス内で処理を切り替えるために利用される機能です。
Javaオーバーライドの使い方
Javaでオーバーライドを定義するにはメソッド名が同じで引数の数や型が全く同じである必要があります。
またメソッドの戻り値についても型を揃えておく必要があるため意識しておきましょう。
記述方法
オーバーライドは下記のように継承関係のなかで同名メソッドを定義します。
親クラス { メソッド名() { // 処理1 } } 子クラス extends 親クラス { メソッド名() { // 処理2 } }
子クラスのメソッドを呼び出した場合、子クラスのメソッドに定義された処理2が実行されます。
記述法だけだと使い所が分かりにくいと思いますのでもう少し具体的に使い方を確認していきましょう。
使い方
オーバーライドの主な使い方は2つです。
- 処理を上書きする
- 処理を追加する
処理を上書きする
記述法でも触れましたが、子クラスで同名メソッドを呼び出した場合には、子クラスに定義された処理が実行されます。
そのため、親クラスとは全く異なる処理を同名メソッドで定義することも可能です。
処理を丸々上書きすることで、親クラスに記述された処理の影響を全く受けないメリットがあります。
処理を追加する
もう1つの使い方として、親クラスで定義された処理を利用しつつ子クラスで追加の処理を記述する方法です。
「super」句を利用すれば、子クラス側から親クラスの処理を利用することができ、更に子クラス独自の処理を追加で定義することも可能です。
Javaオーバーライド利用の注意点
Javaでオーバーライド機能を利用するには、いくつかの条件が存在します。
またアノテーションを利用することで、コンパイル前にオーバーライドの文法エラーチェックが可能となるため、活用することをおすすめします。
オーバーライド条件
子クラスのメソッドは、親クラスのメソッドと下記6つの条件を一致させる必要があるので意識しておきましょう。
- メソッド名が同じ
- 引数の数が同じ
- 引数の型が同じ
- 引数の順番が同じ
- 戻り値の型が同じ
- アクセス修飾子が同等または緩い条件の修飾子
オーバーライド不可条件
オーバーライドが利用出来ない条件は下記2つの条件となります。
- 親クラスのメソッドにfinalが指定されている
- 親クラスのメソッドがstaticメソッド
オーバーライド必須条件
親クラスが抽象クラスで、抽象メソッドが定義されている場合、子クラスではオーバーライドが必須条件となります。
抽象メソッドをオーバーライドして定義しないとコンパイル出来ないので意識しておきましょう。
アノテーション
オーバーライド利用時に必須というわけではありませんが「@Override」のアノテーションを付けることで、オーバーライドしていることを明示することが出来ます。
オーバーライドのアノテーションを利用することで、コンパイルする前に文法エラーがないか確認することが出来るようになります。
スペルミスなどで親クラスに存在しないメソッドを定義してしまう誤りを未然に防ぐことが可能です。
オーバーライドを使用したJavaサンプル
では実際にJavaのサンプルコードでオーバーライドの処理を確認していきましょう。
サンプル1: 上書き処理
public class Main { public static void main(String[] args) { ParentClass parent = new ParentClass(); ChildClass child = new ChildClass(); parent.execute("親クラスから呼び出しています。"); child.execute("子クラス"); } } class ParentClass { void execute(String str) { System.out.println(str); } } class ChildClass extends ParentClass { @Override void execute(String str) { System.out.println("引数の値は" + str + "です。"); } }
実行結果が下記です。
親クラスから呼び出しています。 引数の値は子クラスです。
親クラスと子クラスで同じ名前の「execute」というメソッドを定義していますが、それぞれのインスタンスを作成してexecuteメソッドを実行した結果、子クラスでは処理を上書きして実行されていることが分かります。
サンプル2: 追加処理
子クラス側でsuper句を利用することにより、親クラスの同名メソッドを呼び出すことも可能です。
public class Main { public static void main(String[] args) { ChildClass child = new ChildClass(); child.execute("子クラス"); } } class ParentClass { void execute(String str) { System.out.println(str); } } class ChildClass extends ParentClass { @Override void execute(String str) { super.execute("親クラスのメソッドを呼び出しています。"); System.out.println("引数の値は" + str + "です。"); } }
実行結果が下記です。
親クラスのメソッドを呼び出しています。 引数の値は子クラスです。
17行目に記述している「super.execute」により、親クラスのexecuteメソッドに定義された処理を呼び出しています。
加えて18行目では子クラスに追加した処理を実行しており、同名メソッドで処理を追加出来ていることが確認出来ます。
さいごに: Javaのオーバーライドを活用してコーディング量を減らそう
本記事では、Javaのオーバーライドについての概要から基本的な使い方、利用する際の注意点をご紹介してきました。
オーバーライド機能を利用することにより、処理のアレンジが可能でかつ、親クラスの処理を活用することでコーディング量を減らすことも可能です。
継承クラスのメリットを生かして、積極的にオーバーライドの機能を活用してみてください。