北海道苫小牧市出身の初老PGが書くブログ

永遠のプログラマを夢見る、苫小牧市出身のおじさんのちらしの裏

コンストラクタもわからないとは・・・(2)

コンストラクタについてわかりやすい説明はないか探していたところ、詳しく書かれたページを発見。

        if( そのクラスが、ルートクラスである Object である ) {
                /* なにもしない */
                return;
        }
        引数形式に合致するコンストラクタを選ぶ
        if( そのコンストラクタが this(...) で始まる ) {
                this(...) で示されるコンストラクタを適切な引数で呼び出す
        } else if( そのコンストラクタが super(...) で始まる ) {
                super() で示される親クラスのコンストラクタを適切な引数で呼び出す
        } else {
                super() で親クラスのコンストラクタを無引数で呼び出す
        }

        そのコンストラクタのsuper(),this() 以降の式文を実行していく

これによると、コンストラクタの先頭でsuper()としなくても、自動でsuper()が呼ばれることになり*1前回の考察と一致する。

2. コンストラクタが存在しないときには、あたかも public theClass() { super(); } が定義されているかのようにコンパイラはデフォルトコンストラクタを生成する。

5. この引数コンストラクタの継承のときに、当然引数のあるコンストラクタを定義するが、引数のあるコンストラクタを定義してしまうと、コンパイラはデフォルトコンストラクタの生成を抑止してしまう。つまり、引数のあるコンストラクタを定義した場合には、引数のないコンストラクタも適当な初期値で初期化するようなものを定義する必要がある。無引数コンストラクタの存在を前提とするインスタンス生成方法が別にあるので、その対応が必要である場合が多い。

これは、引数コンストラクタのみを宣言した場合、サブクラスではsuper(引数)の記述を省略出来ないことの説明となる。現に、以下のコードはコンパイル出来ない。

class Test1 {
    Test1(String str){
	System.out.println("Test1's new with String");
    }
}

class Test2 extends Test1{
    Test2(String str){
	System.out.println("Test2's new with String");
    }
}

/*
    以下のようなエラーとなる
    test.java:28: cannot find symbol
    symbol  : constructor Test1()
    location: class Test1
        Test2(String str){
                         ^
    1 error
*/

*1:elseの部分