継承

#継承の基礎
##考え方
継承とは、あるクラスに派生する別のクラスを生成する際に使用する。
例えば、既に「ヒーロー」クラスがあり、それに派生する「スーパーヒーロー」クラスを生成する際に使用する。

##使用方法

```java
class クラス名　extends 元にするクラス名{
元のクラス名に追加するメンバ
}
```

###例
（Heroクラス）

```java
public class Hero {
	//フィールド
	private String name;
	private int hp;
}
```
これに空を飛ぶスーパーヒーローを追加したい場合・・・

(SuperHeroクラス)

```java
public class SuperHero extends Hero{
	private boolean flying;

	public void fly() {
		this.flying = true;
		System.out.println("飛び上がった！");
	}

	public void land() {
		this.flying = false;
		System.out.println("着地した！");
	}
}

```
##継承関係の表現方法
「元のクラス」・・・親クラス、スーパークラス
「元のクラスを元に作成したクラス」・・・子クラス、サブクラス

上記のコードでいうと、継承関係は以下の通り。
「Heroクラス」・・・親クラス、スーパークラス
「SuperHeroクラス」・・・子クラス、サブクラス


##継承の禁止事項
・継承時に複数の親クラスを継承（多重継承）出来ない。
・クラス作成時に`final`が付いたクラスは、継承不可。

#オーバーライド

##考え方
親クラスのメンバを、子クラスで書き換えること。この時親クラスのメンバは書き変わらない。

##例
runメソッドを書き換えたい場合。
(親クラス)

```java
public class Hero {
	//フィールド
	private String name;
	private int hp;

	public void run() {
		System.out.println("逃げ出した！");
	}
```

(子クラス)

```java
public class SuperHero extends Hero{
	private boolean flying;

	public void run() {//書き変えるメンバ
		System.out.println("撤退した！");
	}
}
```
(メインクラス)

```java

public static void main(String[] args) {
		//ヒーロー
		Hero hero1 = new Hero();
		hero1.run();

		//スーパーヒーロー
		SuperHero shHero1 = new SuperHero();
		shHero1.run();
	}
```
（出力結果）

```java
逃げ出した！
撤退した！
```
##オーバーライドの禁止方法
オーバライド禁止のメソッドに`final`を付ける事で、禁止出来る。

###例
runメソッドのオーバーライドを禁止したい場合。
`public final void run`

#継承時のクラス状態

##考え方
上記で作成した、`SuperHero`インスタンスは、`Heroインスタンス`と`SuperHero`インスタンスの２重構造になっている。


（イメージ図）
<img width="473" alt="スクリーンショット 2018-02-26 10.37.12.png" src="https://qiita-image-store.s3.amazonaws.com/0/229025/d58f9b1a-eef0-4d21-76e2-18e5d794c5ca.png">

##呼び出し時の動作
呼び出し時は、まずSuperHeroインスタンスのメンバから利用するよう動作する。

（イメージ図）
<img width="772" alt="スクリーンショット 2018-02-26 10.42.45.png" src="https://qiita-image-store.s3.amazonaws.com/0/229025/288c8454-ab9f-d954-733a-9a47e46f96c0.png">


この場合`runメソッド`は'SuperHero`内にあるため、そちらが呼び出される。
そして、①でメソッドが見つかったため、②の呼び出しは実行されない。

#親クラスへのアクセス方法
##考え方
親クラスのメンバを子インスタンスで使用する方法

##使用方法
フィールド・・・`super.フィールド名`
メソッド・・・`super.メソッド名(引数)`

###例
`SuperHeroクラス`の、`attackメソッド`では、飛んでいる場合２回攻撃する。
攻撃の中身は親クラスの`Heroクラス`の`attackメソッド`を使用したい場合。

```java
//Heroクラス
	public void attack(Matango matango) {
		int matangoHp = matango.getHp() - 5;
		matango.setHp(matangoHp);
	}
```

```java
//SuperHeroクラス
	public void attack(Matango matango) {
		super.attack(matango);
		if(this.flying) {
			super.attack(matango);
		}
```

##注意点
親クラスの親クラス（祖父母クラス）へのアクセスは不可。

#継承とコンストラクタについて
##考え方
継承によって生成されているインスタンスは、自身のコンストラクタ呼び出し前に必ず親コンストラクタも呼び出す。

##親クラスのコンストラクタの呼び出し方法
```java
子クラス名(){
    super(引数);
}
```
しかし、何も記載しない場合、**暗黙のsuper**が自動で入る。

##例
(Heroクラス)

```java
Hero(){
	System.out.println("Heroを生成しました");
}
```
(SuperHeroクラス)

```java
SuperHero(){
　　　　　　　　　　　　　　　　//ここに暗黙のsuperが入る
	System.out.println("SuperHeroを生成しました");
}
```

(mainクラス)

```java
SuperHero shHero1 = new SuperHero();
```
(出力結果)
SuperHeroは生成してないが、SuperHeroのコンストラクタが呼び出される。

```
Heroを生成しました
SuperHeroを生成しました

```

##補足
親クラスのコンストラクタに引数が必要な場合は、**super（引数）**の引数に明示的に値を入れる必要がある。

#継承の際の注意点
##is-aの関係
子クラスis-a親クラス（子クラスは親クラスの一種である）が成り立たないとだめ。

##例
○正しい例：　子クラス（TV）ー親クラス（家電製品）「TVは家電製品である」→成り立つ
×誤った例：　子クラス（TV）ー親クラス（自動車）「TVは自動車である」→成り立たない