教本に沿ってやってみたシリーズ、『第10・11章』。
≪使用教材≫スッキリわかるJava入門 第3版 スッキリわかるシリーズ
継承の基本
以前作ったクラスと似通ったクラスを作りたい時、類似したクラスを作成することができる継承という機能がある。
▼Heroクラスを元にしたSuperHeroクラスを定義したいとき
public class SuperHero extends Hero {
このように、extendsを用いれば、元のクラスの差分だけを記述する形で新たなクラスを宣言できる。
元となるクラス(親クラス)、新たに定義されるクラス(子クラス)の関係を継承関係という。
子クラス直下に定義されていないメソッドも、インスタンス化すれば呼び出しが可能。
SuperHero sh = new SuperHero(); // インスタンス化
sh.run();
オーバーライド
親クラスに定義したrunのメソッドを、SuperHeroクラスに限って動きを書き換えたいは、子クラスで再定義できる。
※Stringクラスは継承不可能。
※オーバーライドを禁止したいメソッドには宣言時にfinelを付ける。
継承とコンストラクタ
Javaでは、すべてのコンストラクタは、その先頭で必ず内部インスタンス部分のコンストラクタを呼び出さなければならないというルールがある。
よって、SuperHero(子クラス)は本来、下記のような書き方をしなければならない。
public SuperHero(){
super();
コンストラクタ1行目でHeroを呼び出していない場合、コンパイラによって「super();」という行が自動的に挿入される。
内部インスタンスの初期化を行う
親クラスコンストラクタに引数が指定されている場合、上記のような引数なしの「super();」で親元を呼び出しを行うことは不可能。内部インスタンスの初期化を行うには引数を明示的に渡す必要がある。
is-aの関係
継承はis-aの関係であるかどうかに基づいて利用すべきである。
子クラスは親クラスの一種であるというルールに則ってこそ正しい継承である。
抽象クラスとインターフェース
- abstract
詳細未定のメソッドを抽象メソッドとして宣言できる。
※抽象クラスはnewによるインスタンス化が禁止されている。
継承元のクラスに詳細未定のメソッドが存在している場合、どこかでオーバーライドし、中身を実装する必要がある。
public abstract void attack(Matango m) {
}
- interface
より抽象度の高い、基本的にフィールドを持たないクラスを「インタフェース」として特別扱いすることができる。
public interface Creature {
void run (); // public abstract は省略可能
}
インタフェースに宣言されたメソッドは、自動的にpublicかつabstractになる。
- implements
interfaceクラスを継承して子クラスを実装する。
public class hill implements Creature {…}
- 多重構造
複数の親クラスを継承すること。
Javaでは基本的に多重構造が禁止されているが、インタフェースでは特別に多重構造が許されている。基本的に中身のないインタフェースの継承ならば、定義の重複により混乱を招くことがなく、オーバーライドによって継承先クラス独自の定義の実装が可能なため。
public class PrincessHero implements Hero,Princess,Character{…}
- extends(拡張)
既存のインタフェースを継承して、機能を拡張する。
public interfacde Human extends Creature {
// 追加メソッド
void talk();
void watch();
void hear();
// ~ 親クラスからの継承メソッドを実装する
以上、雑記メモ。次回『多能性』。