継承後のコンストラクタの呼び出し
〈子クラスから親クラスのコンストラクタの呼び出す〉
new superHero( ); // mainメソッドからインスタンスを作れという命令が送られる
① まず、親インスタンス部が作られる
② 外側に子インスタンス部が作られる
③ JVMは自動的に外側のインスタンスの方のコンストラクタを呼び出そうとする
(メンバも外側から全て呼び出すようにJVMではルール化されている)
ただ実際にパソコンを動かすJVMではなく、
パソコンに書き込むための専用言語java内では
「全てのコンストラクタは内部のインスタンス(親インスタンス)からコンストラクタを呼び出さなければいけない」というルールがある
↑
何もしなければ、JVMは外側から呼び出すので、このルールが適用されなくなってしまう
そこで、javaルールを適用させるために、
内側のインスタンスからコンストラクタを呼び出すための記述をする
super(引数);
※ 親インスタンスのメンバを利用するためのsuper.メソッド名とは何も関係がないので注意
ex. public class Hero{ //親クラス
private String name;
public Hero( ){ //コンストラクタ(自動で代入される値)
int hp=100;
}
}
public class SuperHero extends Hero{ //親クラスを継承した子クラス
super( ); //これによって親クラスのコンストラクタを呼び出す
public void fly( ){
....
}
}
イメージ
自動でJVMが外側にアクセスしたらsuper( );で内側に飛ばされる
→これでjavaのルールが適用できる
※ もしプログラマが子クラスのコンストラクタの1行目にsuper( );という行を書いてなかったら、ルールは適用されず動かないのか?
その場合は、「super( );」という行が自動で代入されるから大丈夫
↓
ということは結局、「super( );」は書いても書かなくても自動で実行される
ただ仕組みは知っておこう!
ex. public class Item{ //親クラス
private String name;
private int price;
public Item(String name){ //引数1つのコンストラクタ
this.name=name;
this.price=0;
}
public Item(String name,int price){ //引数2つのコンストラクタ
this.name=name;
this.price=price;
}
}
public class Weapon extends Item{ //親クラスを継承した子クラス
.....
}
public class Main{ //指示クラス
public static void main(String[ ] args){
weapon w=new Weapon( );
//子クラスのインスタンスを生成すると、自動で親クラスに記述されたコンストラクタも実行される(内側から)
↓
記述はなくてもそこには見えないsuper( );が動くので、内側(親クラス)のコンストラクタを呼び出そうとする
ただこの場合だと
親クラスのコンストラクタは引数ありのものしか記述がないので、
見えないsuper( );←引数なし
が動くと対応できるコンストラクタが親クラスにはない
よって、エラーになる
そこで、Weaponクラスのコンストラクタとして、引数ありのものをきちんと記述する(自動で動くものだと引数なしになってしまうので)
ex. public class Weapon extends Item{
public Weapon( ){
super("ななしの剣"); //引数1つのコンストラクタ
}
}
☆ 子クラスのコンストラクタは必ず親クラスと対応するように記述する
※ちなみに、親クラスのコンストラクタを呼び出すsuper( )と
他のクラスのコンストラクタを呼び出すthis( )は
コンストラクタの先頭行にしか記述できないので注意