継承
Javaの部品クラスのほとんどは、機能を追加できるようになっている。これを「クラスを拡張する」という。
- extendsキーワードによりほかのクラスを継承することが出来る
- 継承元をスーパークラス(親クラス),継承先をサブクラス(子クラス)という
- サブクラスはスーパークラスのフィールドとメソッドを引き継ぐ
- サブクラスは機能を追加してスーパークラスを拡張出来る
- //親クラス(スーパークラス)
- public class Adder {
- double x;
- public void add(double x) {
- this.x += x;
- }
-
- public double getX() {
- return x;
- }
- }
-
- //子クラス(サブクラス)
- public class MyAdder extends Adder {
- double m;
- public void setM(){
- m = x; //スーパーくらすのメンバ変数xを使用している
- }
- public double getM(){
- return m;
- }
- }
-
クラスの階層
クラスが一度に継承できるスーパークラスはひとつだけです。これを単一継承といいます。
継承ツリー
- 継承ツリーの中では子孫は全ての祖先の機能を受け継ぐ
- 継承は単一継承である
継承されないもの
1)オブジェクトの中に取り込まれないもの
- コンストラクタ
- 静的(static)メンバ,クラス変数、クラスメソッド
2)制限があって継承出来ないもの
- final修飾されたクラス (例:Stringクラス)
- privateアクセスのメンバ
Objectクラス
- クラスの宣言にextendsがなければ、 コンバイラが"extends Object"を自動的に挿入する
- Javaの全てのクラスはObjectクラスのサブクラスである
主なObjectクラスのメソッド
メソッド名 | 機能 |
public String toString() | オブジェクトの文字列表現を返す |
public boolean equals(Object o) | オブジェクトがoと等しい時trueを返す |
public int hashCode() | オブジェクトのハッシュコードを返す |
public void notify() | 待機中のスレッドを一つ実行に移す |
public void wait(long t) | tミリ秒(1/1000秒)だけスレッドを休止する |
継承とデフォルトコンストラクタ
クラスにコンストラクタが定義してない時、コンパイラがデフォルトコンストラクタを暗黙のうちに作成する
継承では、サブクラスにおけるコンストラクタ呼び出しが次々とスーパークラスに波及します。
継承では、サブクラスにおけるコンストラクタ呼び出しが次々とスーパークラスに波及します。
コンストラクタの生成規則
Objectクラスを除くすべてのコンストラクタは、実行に先立ってスーパークラスのコンストラクタを呼び出さないといけない。
この原則が確実に実行されるようにするために、Javaコンパイラは次のような規則にしたがってプログラマーが作成したコンストラクタを自動修正する
規則 A)コンストラクタを定義してない時はデフォストコンストラクタを作成し、その中に引数のないスーパークラスのコンストラクタ呼び出しsuper()を含める
規則 B) コンストラクタが定義してあっても、その中にsuper()が含まれない場合、そのコンストラクタの先頭行にsuper()を挿入する
規則 C)デフォルトコンストラクタのアクセス修飾子はクラスのアクセス修飾子とおなじになる
この原則が確実に実行されるようにするために、Javaコンパイラは次のような規則にしたがってプログラマーが作成したコンストラクタを自動修正する
規則 A)コンストラクタを定義してない時はデフォストコンストラクタを作成し、その中に引数のないスーパークラスのコンストラクタ呼び出しsuper()を含める
規則 B) コンストラクタが定義してあっても、その中にsuper()が含まれない場合、そのコンストラクタの先頭行にsuper()を挿入する
規則 C)デフォルトコンストラクタのアクセス修飾子はクラスのアクセス修飾子とおなじになる
明示的なスーパークラスの呼び出し
- スーパークラスにコンストラクタが定義してあり、引数を持つコンストラクタの場合、サブクラスでは引数を持つsuper(引数)を明示的に記述する必要がある
- super(..)はコンストラクタの先頭行に書かないといけない。(コンパイラに自動挿入させないため)
class Parent {
String name;
public Parent(String p){
name = p;
}
}
class Child extends Parent {
public Child(String name){
super(name); //明示的にスーパークラスを初期化しなくてはならない
}
}