継承
継承の基礎
考え方
継承とは、あるクラスに派生する別のクラスを生成する際に使用する。
例えば、既に「ヒーロー」クラスがあり、それに派生する「スーパーヒーロー」クラスを生成する際に使用する。
使用方法
class クラス名 extends 元にするクラス名{
元のクラス名に追加するメンバ
}
例
(Heroクラス)
public class Hero {
//フィールド
private String name;
private int hp;
}
これに空を飛ぶスーパーヒーローを追加したい場合・・・
(SuperHeroクラス)
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メソッドを書き換えたい場合。
(親クラス)
public class Hero {
//フィールド
private String name;
private int hp;
public void run() {
System.out.println("逃げ出した!");
}
(子クラス)
public class SuperHero extends Hero{
private boolean flying;
public void run() {//書き変えるメンバ
System.out.println("撤退した!");
}
}
(メインクラス)
public static void main(String[] args) {
//ヒーロー
Hero hero1 = new Hero();
hero1.run();
//スーパーヒーロー
SuperHero shHero1 = new SuperHero();
shHero1.run();
}
(出力結果)
逃げ出した!
撤退した!
オーバーライドの禁止方法
オーバライド禁止のメソッドにfinal
を付ける事で、禁止出来る。
例
runメソッドのオーバーライドを禁止したい場合。
public final void run
継承時のクラス状態
考え方
上記で作成した、SuperHero
インスタンスは、Heroインスタンス
とSuperHero
インスタンスの2重構造になっている。
呼び出し時の動作
呼び出し時は、まずSuperHeroインスタンスのメンバから利用するよう動作する。
この場合runメソッド
は'SuperHero`内にあるため、そちらが呼び出される。
そして、①でメソッドが見つかったため、②の呼び出しは実行されない。
親クラスへのアクセス方法
考え方
親クラスのメンバを子インスタンスで使用する方法
使用方法
フィールド・・・super.フィールド名
メソッド・・・super.メソッド名(引数)
例
SuperHeroクラス
の、attackメソッド
では、飛んでいる場合2回攻撃する。
攻撃の中身は親クラスのHeroクラス
のattackメソッド
を使用したい場合。
//Heroクラス
public void attack(Matango matango) {
int matangoHp = matango.getHp() - 5;
matango.setHp(matangoHp);
}
//SuperHeroクラス
public void attack(Matango matango) {
super.attack(matango);
if(this.flying) {
super.attack(matango);
}
注意点
親クラスの親クラス(祖父母クラス)へのアクセスは不可。
継承とコンストラクタについて
考え方
継承によって生成されているインスタンスは、自身のコンストラクタ呼び出し前に必ず親コンストラクタも呼び出す。
親クラスのコンストラクタの呼び出し方法
子クラス名(){
super(引数);
}
しかし、何も記載しない場合、暗黙のsuperが自動で入る。
例
(Heroクラス)
Hero(){
System.out.println("Heroを生成しました");
}
(SuperHeroクラス)
SuperHero(){
//ここに暗黙のsuperが入る
System.out.println("SuperHeroを生成しました");
}
(mainクラス)
SuperHero shHero1 = new SuperHero();
(出力結果)
SuperHeroは生成してないが、SuperHeroのコンストラクタが呼び出される。
Heroを生成しました
SuperHeroを生成しました
補足
親クラスのコンストラクタに引数が必要な場合は、super(引数)の引数に明示的に値を入れる必要がある。
継承の際の注意点
is-aの関係
子クラスis-a親クラス(子クラスは親クラスの一種である)が成り立たないとだめ。
例
○正しい例: 子クラス(TV)ー親クラス(家電製品)「TVは家電製品である」→成り立つ
×誤った例: 子クラス(TV)ー親クラス(自動車)「TVは自動車である」→成り立たない
Author And Source
この問題について(継承), 我々は、より多くの情報をここで見つけました https://qiita.com/k_sk193/items/4a4dd065ebd6b27efd9b著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .