2015-08-15 7 views
-2

Почему выход:Как работает конструктор наследования Java?

> B.foo(): bar = null 
> B.foo(): bar = B.bar 
>a.bar = A.bar 
>B.foo(): bar =B.bar 

НО: не

> B.foo(): bar = null 
> A.foo(): bar = A.bar 
>a.bar = A.bar 
>B.foo(): bar =B.bar 

1) B распространяется так же не предположить, называют в класс в? 2) Почему класс a.bar A называется, а не B? 3) Можете ли вы объяснить вывод? код:

public class A { 
    String bar= "A.bar"; 
    A() { foo(); } 
    public void foo() { 
     System.out.println("A.foo(): bar = "+ bar); 
    } 
} 
public class B extends A { 
    String bar= "B.bar"; 
    B() { foo(); } 
    public void foo() { 
     System.out.println("B.foo(): bar = "+ bar); 
    } 
} 
public class C { 
    public static void main(String[] args) { 
     A a= newB(); 
     System.out.println("a.bar = "+ a.bar); 
     a.foo(); 
    } 
} 
+0

Пожалуйста, исправьте свой код. Он не будет компилироваться, как есть. – Carcigenicate

+0

почему по строке: «A a = новый B();» выход имеет две линии? – user

+0

Методы могут быть переопределены, полей быть не может. [Этот вопрос может помочь объяснить] (http://stackoverflow.com/questions/9414990/if-you-override-a-field-in-a-subclass-of-a-class- the-subclass-has-two- fields-wi) почему два поля с тем же именем не обрабатываются так же, как два метода с одной и той же сигнатурой. – Obicere

ответ

2

При вызове класса, который имеет наследование, конструктор родителя вызывается первым.

В этом случае сначала запускается конструктор для A. Конструктор для B вызывается вторым.

B.foo(): bar = null // output from B.foo() invoked from A's constructor 
B.foo(): bar = B.bar // output from B.foo() invoked from B's constructor 

В обоих случаях конструкторы вызвать foo(). Несмотря на то, что Foo() определяется в обоих классах, потому что foo() «s вызов является полиморфным, и экземпляр создается имеет тип B, в как конструктор заклятий, это B» S foo() метод, который называется , Вот почему обе выходные линии начинаются с B.foo(): bar = ....

И, наконец, причина, почему первая строка выводит = null вместо B.bar потому, что он пытается вывести значение переменной bar внутри B класса перед темB класса даже начало инициализирует его поле, поэтому значение остается null. Bbar переменная только инициализируется после Конструктор A завершил свою работу.

Вот почему вы никогда не хотите вызывать переопределяемые методы внутри конструктора классов. Это приводит к неожиданному поведению, подобное этому, когда вы можете непреднамеренно читать неинициализированные поля. This thread объясняет это более подробно.

+0

Большое спасибо !!! – user