9

私はこのデモコードを持っています:

class Test2 extends Test {
    public int number = 0;

    @Override
    public void set(){
        number = 1;
        info();
    }

    @Override
    public void info(){
        System.out.println(number);
    }
}

public class Test {
    public Test(){
        set();
    }

    public void set(){
    }

    public void info(){
    }

    public static void main(String[] args){
        Test2 object = new Test2();
        object.info();
    }
}

コードは次の出力を提供します。

1
0

なんで?私はこの出力を期待しています:

1
1

私の意見では、メイン関数は Test2 クラスのコンストラクターを呼び出してオブジェクトを作成します。コンストラクターは、スーパークラスのコンストラクターを自動的に呼び出します。このコンストラクターは、オーバーライドされるメソッド set() を呼び出します。したがって、クラス Test2 のメソッド set() が呼び出されます。このメソッドはフィールドを設定し、数値を書き込む info() メソッドを呼び出します。次に、メイン関数は、作成されたオブジェクトの info() メソッドを再度呼び出します。

最初の行の出力が「1」であるため、数値フィールドは正しく設定されています。しかし、なぜ 2 行目に 0 が含まれているのでしょうか。フィールドがまったく設定されていないようです。説明できますか?

期待どおりの動作を得るにはどうすればよいですか? 前もって感謝します!

4

3 に答える 3

18
class Test2 {
    public int number = 0;
}

と同等です

class Test2 {
    public int number;

    public Test2() {
        super();
        number = 0;
    }
}

したがって、スーパーコンストラクターを呼び出すことにより、フィールドnumberは1に設定されます。スーパーコンストラクターから戻った後、number0への割り当てが実行されます。

割り当てを削除するだけで、期待どおりに動作するはずです。

于 2012-08-23T21:53:10.723 に答える
1

あなたのコードは Java のゴールデン ルールを破っています。つまり、サブクラスによってオーバーライドできるコンストラクターのメソッドを決して呼び出さないでください。つまり、そのようなメソッドはプライベートにする必要があります。

Test2 のデフォルト コンストラクターが完了するまでに、初期化子によって割り当てられた初期値 1 が上書きされますpublic int number = 0;

于 2012-08-23T21:59:01.700 に答える