Почему мой дочерний класс не инициализирует переменные должным образом в Java - PullRequest
0 голосов
/ 30 мая 2011

В приведенном ниже коде myString всегда инициализируется нулем.Я должен вручную инициализировать в init () или подобное.Насколько я могу судить, это связано с суперклассом / подклассом, но я не понимаю точного механизма

public class A extends B {

    private String myString = "test";


    public static void main(String[] args) {
        new A();
    }

    public A() {
        super();

    }

    public void c() {
        System.out.println(myString);
    }

}

public class B {

    public B() {
        c();
    }

    public void c() {

    }
}

Ответы [ 3 ]

3 голосов
/ 30 мая 2011

Проблема с вашим кодом заключается в том, что myString инициализируется в начале конструктора класса A, но справа после супер-конструктора (то есть класса B). Поскольку вы обращаетесь к переменной ранее из конструктора класса B (косвенно через вызов переопределенного метода c), вы получаете это поведение.

Как правило: если вы хотите избежать непредвиденного поведения, не вызывайте переопределенные методы до выполнения конструктора.

0 голосов
/ 30 мая 2011

Thinking in Java Second Edition, Брюс Экель, Поведение полиморфных методов внутри конструкторов (стр. 337-339).

0 голосов
/ 30 мая 2011

Добавьте вызов к методу c(); overidden сразу после того, как объект полностью создан и вызов конструктора суперкласса завершен.

Измените свой код на этот ..

public class A extends B {

    private String myString = "test";


    public static void main(String[] args) {
        new A();
    }

    public A() {
        super();
         c();     // Include the call to c(); here ...

    }

    public void c() {
        System.out.println(myString);
    }

}

public class B {

    public B() {

    }

    public void c() {

    }
} 

 // Output : test
...