5

同様の質問をオンラインで検索しましたが、見つかりませんでした。ということで、こちらに投稿。

次のプログラムで、'i' の値が 100 と出力されるのはなぜですか?

私の知る限り、「これ」は現在のオブジェクトを指します。この場合は「TestChild」で、クラス名も正しく出力されます。しかし、なぜインスタンス変数の値が 200 でないのでしょうか?

public class TestParentChild {
    public static void main(String[] args) {
        new TestChild().printName();
    }
}

class TestChild extends TestParent{
    public int i = 200;
}

class TestParent{
    public int i = 100;
    public void printName(){
        System.err.println(this.getClass().getName());
        System.err.println(this.i); //Shouldn't this print 200
    }
}

さらに、次の出力は期待どおりです。親クラスから「 this.test() 」を呼び出すと、子クラスのメソッドが呼び出されます。

public class TestParentChild {
    public static void main(String[] args) {
        new TestChild().printName();
    }
}

class TestChild extends TestParent{
    public int i = 200;
    public void test(){
        System.err.println("Child Class : "+i);
    }

}

class TestParent{
    public int i = 100;
    public void printName(){
        System.err.println(this.getClass().getName());
        System.err.println(this.i); //Shouldn't this print 200
        this.test();
    }
    public void test(){
        System.err.println("Parent Class : "+i);
    }
}
4

3 に答える 3

7

Java には仮想フィールドがないため、iフィールドはprintName常に参照しTestParent.i、子孫の子は参照しません。

Java での継承によるポリモーフィズムはメソッドでのみ発生するため、説明している動作が必要な場合は、次のようにします。

class TestChild extends TestParent{

    private int i = 200;

    @Override
    public int getI() { return this.i; }
}

class TestParent{

    private int i = 100;

    public int getI() { return this.i; }

    public void printName(){
        System.err.println( this.getClass().getName() );
        System.err.println( this.getI() ); // this will print 200
    }
}
于 2012-12-31T05:11:54.357 に答える
2

クラス変数をオーバーライドする方法はありません。

Java ではクラス変数をオーバーライドせず、代わりに非表示にします。オーバーライドはインスタンス メソッドであり、非表示はオーバーライドとは異なります。

あなたが与えた例では、クラスで「i」という名前のクラス変数を宣言することにより、同じ名前「i」のTestChildスーパークラスから継承したクラス変数を非表示にします。TestParentこの方法で変数を非表示にしても、スーパークラスのクラス変数 'i' の値には影響しませんTestParent

目的の動作を得るには、getI()メソッドをオーバーライドするだけです

class TestChild extends TestParent{

    private int i = 200;

    @Override
    public int getI() {
         return this.i;
    }
}
于 2012-12-31T05:17:37.640 に答える
2

Java のフィールドは継承されないためです。宣言を使用すると、 という名前の 2 つの異なるフィールドが効果的に宣言されi、 のインスタンスにTestChildは両方が含まれます。がTestParentコンパイルされるとi、そのメソッド内の への参照は常に を参照しTestParent.iます。

于 2012-12-31T05:13:12.643 に答える