public class Solution {
public static void main(String[] args) {
new B(6);
}
public static class A {
private int f1 = 7;
public A(int f1) {
this.f1 = f1;
initialize();
}
protected void initialize() {
System.out.println(f1);
}
}
public static class B extends A {
protected int f1 = 3;
public B(int f1) {
super(f1);
this.f1 += f1;
initialize();
}
protected void initialize() {
System.out.println(f1);
}
}
}
Здравствуйте, код выдает 0 9. Подскажите пожалуйста, почему если поменять модификатор метода initialize() в классе А на private, то получаем 6 9 ? Инициализация все равно же начинается с класса-родителя. Как меняется механизм?
Конструкторы класса не должны вызывать переопределяемые методы, непосредственно или опосредованно. Нарушение этого правила может привести к аварийному завершению программы. Конструктор суперкласса выполняется прежде конструктора подкласса, а потому переопределяющий метод в подклассе будет вызываться перед запуском конструктора этого подкласса. И если переопределенный метод зависит от инициализации, которую осуществляет конструктор подкласса, то этот метод будет работать совсем не так, как ожидалось.
Дж.Блох, Эффективное программирование на Java
именно это Ваш код и делает - вызывает переопределяемый метод в конструкторе суперкласса. В результате вызывается метод наследника, что никак не ожидаемо. При объявлении же метода как private наследования как такового не происходит, в субклассе создается метод, совпадающий по сигнатуре и имени с приватным методом суперкласса и конструкторы теперь "стучатся" к методам своих классов.
Виртуальный выделенный сервер (VDS) становится отличным выбором
как пользоваться Selenium на Android, как заходить на сайта не открывая браузер ?
Что быстрее запишется, вывод разделенный на файлы или при записи в один файл?
Некоторое непонимание появилось при просмотре обучающих видеоЕсть ли разница между просто установленным Box2D и Box2D, который можно выборочно...