viperz
@viperz
inspired by Java

Вызов метода наследника в конструкторе родителя?

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();
        }

        private 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);
        }
    }
}


В этом примере в конструкторе класса А будет вызван метод initialize() класса А, но если сделать так, то уже вызывается метод класс В, который не успел инициализировать свою переменную f1:
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);
        }
    }
}


Если второй пример я смутно осознаю (хотя до конца всё равно нет), то первый - совершенно не понимаю.
Почему сужение области видимости (private) позволяет вызвать метод родителя?
Так же объясните ,пожалуйста, что происходит на самом деле и почему в том примере, где из конструктора родителя вызывается метод наследника.
  • Вопрос задан
  • 2228 просмотров
Решения вопроса 1
Vestail
@Vestail
Software Engineer
В первом случае т.к. A.initialize() помечен как private, в классе B создается свой собственный метод B.initialize() . Поэтому результат будет 69, сначала выполнится A.initialize(), а после B.initialize(). Но во втором случае этот метод наследуется и переопределяется, поэтому в конструкторе класса А будет вызвана версия Initialize() из B(в java классы по умолчанию виртуальные). Но т.к. производный класс инициализируется после базового, то результат будет 09(поле f1 в классе B еще не успело инициализироваться и содержит стандартное значение, но его уже выводят).
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы