Приоритет переопределенного метода в наследнике
Есть, будем говорить, учебный код
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" и как сделать "6 9".
Вопрос вот в чем: почему при вызове initialize() в конструкторе A срабатывает метод класса B? Выходит по умолчанию, если есть выбор, то срабатывает метод наследника? А если сделаем initialize() в А private, то унаследовать метод нельзя, выбора нет и отработает метод в классе A. Так?
Ответы (2 шт):
Выводится "0 9" из-за порядка инициализации https://ru.stackoverflow.com/a/464038/276430, поля с одинаковыми именами не перегружаются как методы. Получается тут 2 разные переменные, одна в A, другая в B.
Вызывать такие initialize методы всё же лучше после конструирования объекта, т.е. не в конструкторах, а снаружи (тут в main). Также чтобы "проинициализировался" родитель, нужно вызвать в переопределённом методе метод родителя super.initialize();
public class Solution {
public static void main() throws Exception {
B b = new B(6);
b.initialize();
}
public static class A {
private int f1 = 7;
public A(int f1) {
this.f1 = f1;
}
protected void initialize() {
System.out.println(f1 + " A");
}
}
public static class B extends A {
protected int f1 = 3;
public B(int f1) {
super(f1);
this.f1 += f1;
}
@Override
protected void initialize() {
super.initialize();
System.out.println(f1 + " B");
}
}
}
Вам в ответе выше (Drawn Raccoon) отписал почему в текущем варианте не будет работать и как сделать правильно, но имеется еще один вариант решения вашей проблемы (хоть и не очень безопасный, не рекомендуется вызывать методы из конструктора, но я частично закрыл проблему за счет добавления модификатора final на критичные методы):
public class Solution {
public static void main(String[] args) {
new B(6);
}
static class A {
private int field;
A(int field) {
setField(field);
initialize();
}
final int getField() {
return field;
}
final void setField(int field) {
this.field = field;
}
final void initialize() {
System.out.println(getField());
}
}
public static class B extends A {
B(int field) {
super(field);
setField(getField() + 3);
initialize();
}
}
}