@634

thisとsuper その3

Advertisement

動作

まず、今回のポイント。
コンストラクタの一行目には自動的にsuper()が挿入される(親クラスのデフォルトコンストラクタ呼び出し)

クラス作成時にコンストラクタを1個も作っていないと、デフォルトコンストラクタ(引数のないコンストラクタ)をコンパイラが自動的に挿入する。その挿入されたデフォルトコンストラクタからもsuper()が呼ばれる。

ややこしい話
親クラスのコンストラクタ呼び出しは、ひとつのコンストラクタにひとつしか記述できない(しかもコンストラクタの先頭行に書かなければならない)から、ユーザがsuper()を記述している場合は、挿入は行われない。

ちょっと実験。
public class DcTest{
    public static void main(String args[]){
        Test2 t2 = new Test2();
        t2.resultOutput();
    }
}

class Test{
    int num;

    public Test(){
        num = 10;
    }

    public void resultOutput(){
        System.out.println(num);
    }
}

class Test2 extends Test{
    public void resultOutput(){
        System.out.println(num);
    }
}
結果
10
Test2のnumが10になった。

これはTest2に勝手に挿入されたデフォルトコンストラクタ内でスーパークラスのコンストラクタを呼んでいるからだ。

注意するトコ。

注意点1:コンストラクタを1つでも作っているとデフォルトコンストラクタは挿入されない。

問題記述
スーパークラスには引数が1個以上のコンストラクタを記述。デフォルトコンストラクタはなし。サブクラスにはコンストラクタなし。
この場合、サブクラスにはスーパークラスのデフォルトコンストラクタを呼ぶデフォルトコンストラクタが勝手に挿入されるんだけど、スーパークラスにはデフォルトコンストラクタがない。

実験↓
public class CoTest{
    public static void main(String args[]){
        Test2 t2 = new Test2();
        t2.resultOutput();
    }
}

class Test{
    int num;

    //引数を持つコンストラクタ
    public Test(int n){
        num = n;
    }
}

class Test2 extends Test{
    //コンストラクタなし。

    public void resultOutput(){
        System.out.println(num);
    }
}
コンパイルの結果
coTest.java:16: シンボルを解決できません。
シンボル: コンストラクタ Test ()
場所    : Test の クラス
class Test2 extends Test{
^
この問題を知らないでこのエラーがでると、どこが間違ってるのかわからなくなる。

注意点2:サブクラスのコンストラクタからはスーパークラスのデフォルトコンストラクタが呼ばれる。

ここでの問題記述
サブクラスにはコンストラクタを記述。スーパークラスには引数1個のコンストラクタ
上とほとんど同じなんだけど、たとえサブクラスにコンストラクタを作っていても、結局最初にsuper()が呼ばれるからダメ。

実験↓
public class CoTest{
    public static void main(String args[]){
        Test2 t2 = new Test2(10);
        t2.resultOutput();
    }
}

class Test{
    int num;

    public Test(){
        num = 10;
    }
}

class Test2 extends Test{
    public Test2(){};
	
    public Test2(int n){
        num += n;
    }

    public void resultOutput(){
        System.out.println(num);
    }
}
結果。
coTest.java:16: シンボルを解決できません。
シンボル: コンストラクタ Test ()
場所    : Test の クラス
class Test2 extends Test{
^
まとめ。
スーパークラスサブクラス結果
デフォルト以外のコンストラクタ記述コンストラクタ省略コンパイルエラー
コンストラクタ省略コンストラクタ省略OK
デフォルト以外のコンストラクタ記述コンストラクタ記述コンパイルエラー
コンストラクタ記述。super()が記述されている。OK。でも、super()で指定した引数と同じ引数を持つコンストラクタがスーパークラスに必要。
たとえ処理がない場合でもすべてのクラスにデフォルトコンストラクタをもたせておけば、今回の問題は回避できる。

Advertisement

ショートカット

634
このカテゴリのトップページに戻る
634labs
   UIコレクションギャラリー

サイト検索

Google

Web サイト内

Y!ログール