【Java】継承とは?オーバーライドとは?まとめてみた

こんにちはkazuです。
本日は継承とオーバーライドについて再度お話していこうと思います。
なぜそのようなことをするかといいますと少しJavaに慣れてきた自分への備忘録として
そして以前よりわかりやすい説明ができるのではないか
継承とオーバーライドはつながりあるということで再度記事にすることに決めました。

継承とは?オーバーライドとは?

一度記事にしたのでこちらも確認していただきたいです。

関連記事

こんにちは、kazuです。 本日はオーバーライドについて 解説していきます。 オーバーライドとは オーバーライドとは、クラスを継承した時に継承元になっているスーパークラス(親クラス)で定義されているメソッドを、継承したサブクラス(子[…]

関連記事

こんにちは、kazuです。 今回はjavaの継承について 解説していきたいと思います。 継承とは何か? 最初に継承とは何かということについてです。 継承とは今あるクラスに追加の機能として新たなクラスを作成することをいいます。 少[…]

しかしわかりずらいと思いますので(自分も見返してなんだこれと思いましたくらいです(笑))
ということで簡単ですがどういうものか書いていこうと思います。

継承

クラスの機能を引き継ぎながら新しいクラスを定義することを継承といいます。
そして継承のクラスには継承元となるクラスのことスーパークラスまたは親クラス、継承のクラスを引き継いでいるクラスのことをサブクラスまたは子クラスと言います。
ということで前回(といいますがだいぶ古い記事ですが。。。)の記事で使用したゲームでの例に挙げたいと思います。
ゲーム皆さんやりますよね?
まずゲームというのはモニターとゲーム機とコントローラーとソフトに関しては共通で用意しないといけないですよね?
でゲーム機とコントローラーとモニターは1種類持っていないと仮定します。(お小遣いが少ないと思ってください。笑)
ですがソフトに関してはいくつか種類があってアクションソフト、恋愛ソフト、RPGソフトがあるとします。
イメージとしては継承なしでは3台も不要であるはずなのにモニターとゲーム機とコントローラーをソフトの数だけ用意しないといけないのです。
継承のないイメージ

class Gameアクション {
  ゲーム機(){};
  モニター(){};
  コントローラー(){};
  ソフト(){
    System.out.println("アクションのソフト");
  };
}
class Game恋愛 {
  ゲーム機(){};
  モニター(){};
  コントローラー(){};
  ソフト(){
    System.out.println("恋愛のソフト");
  };
}
class GameRPG {
  ゲーム機(){};
  モニター(){};
  コントローラー(){};
  ソフト(){
    System.out.println("RPGのソフト");
  };
}

どうですか?
こんなことできますか?少なくともうちではできないです。。
というか不要ですよね?物が増えるだけだし(笑)
それを1台のみにできるのが継承になります。
使用するのがextendsで継承ができてこれでゲーム機とモニターとコントローラーは1つ持っていれば、ゲームをできるようになります。
ではどのような感じになるかというと以下のようになります。
継承のあるイメージ

// スーパークラス
class Game {
  ゲーム機(){};
  モニター(){};
  コントローラー(){};
}
// サブクラス
class RPG extends Game {
  ソフト(){
    System.out.println("RPGのソフト");
  };
}
// サブクラス
class 恋愛 extends Game {
  ソフト(){
    System.out.println("恋愛のソフト");
  };
}
// サブクラス
class アクション extends Game {
  ソフト(){
    System.out.println("アクションのソフト");
  };
}

どうでしょうか?
確かにクラス的には増えてしまったのですが、
コード量や見やすさという面では継承した方が見やすいのではないかと思います。
これが継承するといいます。

オーバーライド

では次にオーバーライドの話をしていこうと思います。
オーバーライドとはクラスを継承した時に元になっているスーパークラスで定義されているメソッドを継承したサブクラスで同じメソッド名を記載して(引数があれば引数も同じ)スーパクラスのメソッドを書き換えることをオーバライドといいます。
この説明ではうーんって感じですよね。
私もそう思います。初心者に優しくない説明だなと。まぁ私の頭が悪いだけかもしれませんが(笑)
では少しイメージしやすいようにたとえを話していきます。
オーバーライドをイメージするのであれば学校には試験ありますよね?
ちなみに私は嫌いでした(どうでもいいと思いますが。)
点数によっては学年順位が変わりますよね。
前回の試験1位2位3位を今回の試験の1位2位3位に書き換えることであります。
少しだけイメージつきましたかね?
コードのようにしてみます

// スーパークラス
class 去年順位 {
  順位(){
    System.out.println("1位 : 近藤勇 88点");
    System.out.println("2位 : 土方歳三 85点");
    System.out.println("3位 : 沖田総司 82点");
 };
}
// サブクラス
class 今年順位 extends 去年順位 {
 @override
  順位(){
    System.out.println("1位 : 坂本龍馬 98点");
    System.out.println("2位 : 大久保利通 95点");
    System.out.println("3位 : 西郷隆盛 92点");
 };
}

コードにするとこんな感じになります!
で実行結果はどうなると思いますか?
それが以下になります。

// 実行結果
1位 : 坂本龍馬 98点
2位 : 大久保利通 95点
3位 : 西郷隆盛 92点

はい見事にサブクラスの今年順位の順位();が実行されていますね。
そしてスーパークラスの去年順位の順位();は呼ばれていませんね
このスーパクラスの順位();をサブクラスの順位();を上書きすることを
オーバーライドといいます。

継承とオーバーライドのサンプルを見てみよう

ではサンプルを見てみましょう!
今回はバイクに関するクラスを作成していきます。
前提知識と知ってほしいのはバイク250cc以上は車検がないということです。

class main {
  public static void main(String[] args){
     ichiro ichiro = new ichiro();
     ichiro.setBike(400,1111)
     ichiro.bikeInfo();
     ichiro.bikeModel();
     System.out.println("---------------------");
     zhiro zhiro = new zhiro();
     zhiro.setBike(50,9999)
     zhiro.bikeInfo();
     zhiro.bikeModel();
  }
}
class bike {
  // 排気量
 private int displacement;
  // ナンバープレート
  private int num;

  // バイクを設定する
  public setBike(int displacement, int num){
    displacement = displacement;
    num = num;
    color = color; 
  }

  // バイクの情報
  public bikeInfo(){
    System.out.println("あなたのバイクのナンバーは" + num + "です!");
    vehicleInspection();
  }

  // 車検
 private vehicleInspection(){
  System.out.println("あなたのバイクの排気量は" + displacement + "ccです!");
  if(displacement > 250){
      System.out.println("あなたのバイクに車検があります");
    } else {
      System.out.println("あなたのバイクに車検がありません");
    }
  }

 // 車種
 public bikeModel(){
    System.out.println("車種はわかりません");
  }
}
public ichiro extends bike {
  @override
  public bikeModel(){
     System.out.println("400ccのバイクです");
     System.out.println("色は青色です");
  }
}
public zhiro extends bike {
  @override
  public bikeModel(){
     System.out.println("50ccのバイクです");
     System.out.println("色は赤色です");
  }
}
// 実行結果

あなたのバイクのナンバーは1111です!
あなたのバイクの排気量は400ccです!
あなたのバイクに車検があります
400ccのバイクです
色は青色です
---------------------
あなたのバイクのナンバーは9999です!
あなたのバイクの排気量は50ccです!
あなたのバイクに車検がありません
50ccのバイクです
色は赤色です

という感じになりますねスーパクラスがbikeクラスそしてサブクラスにはichiroクラスとzhiroクラスがあります。そしてメソッドbikeModel()を見ていただければわかりますがオーバーライドされています。そしてオーバーライドされるとスーパークラスのSystem.out.println("車種はわかりません");が上書きされているのがわかりますでしょうか?
実行結果を見ていただければわかると思います。実行されていないですよね。

スーパクラスの処理を残してオーバーライドしたい

次は先ほどのサンプルではオーバーライドした際スーパークラスの処理が実行されなかったと思います。
ではスーパークラスの処理も実行したいとなったときはどうすればいいのか?ということを説明しようと思います。
結論から言うとスーパークラスの処理を残してオーバーライドは可能です。
実際にコードを見てみましょう。

class main {
  public static void main(String[] args){
    child child = new child();
    child.sample(); 
  }
}
class parent{
  public sample(){
    System.out.println("これはスーパクラスの処理です!");
  }
}
class child extends parent{
 @override
  public sample(){
    super();
    System.out.println("これはサブクラスの処理です!");
  }
}
// 実行結果
これはスーパクラスの処理です!
これはサブクラスの処理です!

これが方法です。どこが違うかわかりましたか?
childクラスのsampleにsuper();があると思います。
これを追加することによりスーパクラスの処理とサブクラスの処理を両方実行することができます!
何も難しいことないでよね?
ただ現場だとオーバーライドなどは複雑化しやすくわかりずらくなると思います。
なので基本は覚えておくとよいと思います!

最後に

いかがでしたでしょうか?
前の記事よりはわかりやすく書けたかなと思います!
この記事があなたのためになればうれしいです。
最後までご覧いただきありがとうございました。