【Java入門(3)オブジェクト指向:活用編 #5】オーバーライド

 

みのる
こんにちは。笑顔で感謝!✨ みのるコーチです。
今回も、ご覧いただき、ありがとうございます。

今回は…

Java入門3 オブジェクト指向:活用編 #5
オーバーライド

というテーマでお送りします。

彩香
着実に進んでいる感覚が、嬉しいです。
今回も、楽しんで学んでいきます。
剛留
また、新しい言葉が出てきましたね。
今回も、頑張ります。

【1】 オーバーライドとは

オーバーライドとは…

サブクラスでスーパークラスのメソッドを
再定義すること。

です。

同じメソッド名・引数・戻り値で
異なる振る舞いをしたい場合に定義します。

オーバーライド
✅ サブクラスでスーパークラスのメソッドを
  再定義すること。

✅ 同じメソッド名・引数・戻り値で
  異なる振る舞いをしたい場合に定義する。

イメージ的には、こうなります。

スーパークラス classA があります。

その中で定義されたメソッド methodX() があります。

サブクラス classB は classA を継承します。
そうすると、methodX() は引き継がれます。

利用する側が、classB をインスタンス化して
methodX() を実行すると…

classA で定義した methodX() が実行されます。

ここまでは、今まで学んできたところですね。

そして、classB の中では、methodX() と
同じ名前・引数・戻り値で メソッドを再定義できます。

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

このように、classB の中で
methodX() をオーバーライドすると…

利用する側が、classB をインスタンス化して
methodX() を実行した時に…

オーバーライドした methodX() が
実行される事となります。

フィールドやメソッドを継承しながら…

あるメソッドについて、同じ名前・引数で
異なる振る舞いをしたい場合に定義します。

このイメージが オーバーライドの基本です。
押さえておきましょう。

彩香
以前に、オーバーロードを学びましたが
それとは、違う意味なのですね。
剛留
確かに、オーバーロード と オーバーライド
似ているから 混乱しそうですね。

「いとこ」みたいな感じですか?

みのる
この部分、混乱してしまう場合もありますが
別物なので、分けて考えましょう。

決して「いとこ」ではありません。
名前の似た「他人」かな~? っと思います。

簡単にまとめておくと、こうなります。

(オーバーロード)

✅ 同一クラスの中で、メソッド名が同じで
  シグネチャ違いのメソッドを定義すること。

✅ 利用する側は、シグネチャを選んで
  呼び出すこととなります。

(オーバーライド)

✅ サブクラスが スーパークラスの
  メソッド(シグネチャ・戻り値が同じ)を
  再定義すること。

✅ 利用する側は、再定義されたメソッドを
  呼び出すこととなる。

今回は…

オーバーライド(サブクラスで再定義)

のお話ですよ。

【2】 条件

オーバーライド(再定義)の条件を
見ていきましょう。

これは、3つあります。

1つ目は…

メソッド名+引数+戻り値が同じ。

ということです。

全て同じでないと、別物ですので
再定義したことにはなりません。

2つ目は…

アクセスレベルは狭くできまない。

ということです。

アクセス修飾子は、広い順に…

public > proteced > (指定なし) > private

…となっています。

3つ目は…

final 修飾子の付いたメソッドは
オーバーライドできない。

ということ。

メソッドを それ以上 オーバーライドされたく
ない場合には final修飾子をつけます。

オーバーライドの条件
✅ メソッド名+引数+戻り値が同じ。

✅ アクセスレベルは狭くできない。

✅ final 修飾子の付いたメソッドは
  オーバーライドできない。

この3つのうち、特に大切なのは1番目です。
押さえておきましょうね。

【3】 final修飾子

final 修飾子について
まとめておきましょう。

メソッドの中で定義する変数や
フィールドに final修飾子がついている場合…

値を1度だけ設定できる事となります。
初期値を設定して定数として使用します。

メソッドに final修飾子がついている場合…

オーバーライドできません。

サブクラスで、メソッドを再定義させたくない場合に
この final修飾子をつけます。

クラスに final修飾子がついている場合…

継承ができません。

それ以上 クラスを継承させたくない場合に
この final修飾子をつける事となります。

final修飾子
(変数)
(フィールド)
 ⇒値を1度だけ設定できる
  定数として使用する。

(メソッド)
 ⇒オーバーライドできない

(クラス)
 ⇒継承できない

final は「最後の」「最終の」という意味なので
イメージは つきやすいと思います。

ここでは、まず 変数・フィールド・メソッド・クラスに
final修飾子がつけられることを 押さえておきましょう。

彩香
final について、一通り解りました。
何だか、スッキリしました。
剛留
final という意味を考えると、理解しやすいです。
また、一歩 前進できました。

【4】 @Override

オーバーライドする時に活用したいのが
オーバーライドアノテーションです。

これは

@Override

…と記述するもので。

これを
メソッドの前に記述することで

スーパークラスのメソッドを
オーバーライドしている事を明示します。

このことによって

正しくオーバーライドされているか
コンパイラがチェックしてくれる。

こととなるのです。

この、オーバーライドアノテーションをつけない
場合を考えると…。

例えば、メソッド名のスペルミスをしてしまった場合も
コンパイラはチャックしてくれません。

別のメソッドとして扱われてしまいますね。

そうすると、間違いに気づかない
という事も 起こってしまいます。

ですので、オーバーライドする時には
必ず この @Override をつけるようにしましょう。

オーバーライドアノテーション
✅ @Override と記述する。

✅ メソッドの前に記述することで
  スーパークラスのメソッドを
  オーバーライドしている事を明示する。

✅ 正しくオーバーライドされているか
  コンパイラがチェックしてくれる。

彩香
質問です。
この、アノテーションって、何なのでしょう?
みのる
不明点を 明確にする姿勢は
とても 素晴らしいですね。

この、アノテーションについてですが。

これは、Javaコード上では…

@で始まるもので…

コードでは表現しきれない情報を
補足としてつけ加えることができます。

今回は、@Override で オーバーライドアノテーション。
メソッドのオーバーライドを 明示する働きをしていましたね。

アノテーション
✅ 「@(アットマーク)」ではじまる。

✅ コードでは表現しきれない情報を
  補足としてつけ加えることができる。

【5】 superキーワード

メソッドをオーバーライドしている場合を
考えましょう。

サブクラスのメソッドの中で…

オーバーライドする前の
スーパークラスのメソッドを 呼び出したい

…場合があります。

まず スーパークラスの処理をして
次に 処理を追加したい場合 などです。

このような時に、スーパークラスの
メソッドにアクセスする方法があります。

それが superキーワードを用いる方法です。

super キーワードは…

スーパークラスで定義したメンバを
明示的に指し示すために使用します。

スーパークラスのメソッドに
アクセスするには…

super.メソッド名(実引数,…)と
記述します。

superキーワード
✅ スーパークラスで定義したメンバを
  明示的に指し示すために使用する。

✅ スーパークラスのメソッドアクセス
  super.メソッド名(実引数,…)

例を見てみましょう。

public class Employee {
   :
  public void displayInfo() {
    :
  }
}

public class SalesEmployee extends Employee {
   :
  @Override
  public void displayInfo() {
    super.displayInfo();
      :
  }
}

例えば、スーパークラス Employee。

extends キーワードで継承した サブクラス が
SalesEmployee の場合を考えます。

Employee で定義したdisplayInfo() を
SalesEmployee でオーバーライドしています。

ここで…

オーバーライドするdisplayInfo()の中で
スーパークラスの displayInfo() を呼び出したい

場合…、このように記述します。

super.displayInfo()

この、superキーワードの使い方も
押さえておきましょう。

剛留
今回の super キーワードもそうですが、super() もあって…。
あと、this と this() もあって…。少し混乱気味です…。
みのる
それでは、ここで this と super について
整理しておきましょう。

キーワード this によるメンバアクセスは…

this の後に、ドット演算子を使用して
自身のインスタンスの メンバにアクセスする方法です。

イメージとしては、このような感じです。

メソッドから、同じインスタンスのメンバに
アクセスするということです。

キーワード super によるメンバアクセスは…

super の後に、ドット演算子を使用して
スーパークラスで定義したメンバに アクセスする方法です。

イメージとしては、このような感じですね。

メソッドから、スーパークラスで定義した
メンバにアクセスします。

this() は インスタンス化する時に、コンストラクタの中で
引数パターン違いの別コンストラクタを呼び出す方法です。

イメージ的には、このような感じになります…。

一つのコンストラクタが、別のコンストラクタを
呼び出す形です。

super() は インスタンス化する時に、コンストラクタの中で
スーパークラスのコンストラクタを呼び出す方法です。

イメージ的には、このような感じです。

サブクラスのコンストラクタが
スーパークラスのコンストラクタを呼び出す形です。

このイメージで、掴んでおくこと大切です。
迷ったら、ここに戻ってきてくださいね。

剛留
まるっと、わかりました。
ノートしたので、いつも 見返します。

【まとめ】

【1】 オーバーライドとは
✅ サブクラスでスーパークラスの
  メソッドを 再定義すること。

✅ オーバーロードとは別物。
  (名前の似た他人…?)

【2】 オーバーライドの条件
✅ メソッド名+引数+戻り値が同じ。

✅ アクセスレベルは狭くできない。

✅ final 修飾子の付いたメソッドは
  オーバーライドできない。

【3】 final修飾子
✅ 変数・フィールド(につけると)
  ⇒値を1度しか設定できない。

✅ メソッド(につけると)
  ⇒オーバーライドできない。

✅ クラス(につけると)
  ⇒継承できない。

【4】 @Override
✅ メソッドの前に記述することで
  スーパークラスのメソッドを
  オーバーライドしている事を明示する。

✅ 正しくオーバーライドされているか
  コンパイラがチェックしてくれる。

【5】 superキーワード
✅ スーパークラスで定義したメンバを
  明示的に指し示すために使用する。

✅ 明示的にスーパークラスで
  定義したメソッドにアクセスする場合。
   super.メソッド名(実引数,…)