У меня есть проблемы со следующими четырьмя классами:Java наследование и замененные методы - Влияние модификаторов
class X {
void a() {
b();
c();
}
void b() {
System.out.println("b from class X");
}
private void c() {
System.out.println("c from class X");
}
}
class Y extends X {
void b() {
System.out.println("b from class Y");
}
}
class Z extends Y {
void b() {
System.out.println("b from class Z");
}
void c() {
System.out.println("c from class Z");
}
}
public class Main {
public static void main(String[] args) {
Y y = new Z();
y.a();
}
}
Пожалуйста, не комментарий разумности классов, это всего лишь пример. Я также пытался следить за потоком JVM с помощью методов, использующих отладчик eclipse, но шаги в этих методах в некоторых случаях немного ускоряются.
я уже получил, что
Y y = new Z();
создает новый экземпляр класса Z и назначить его к ссылке класса Y. Поскольку в Z нет конструктора, компилятор просматривает каждый суперкласс, есть ли конструктор, а в случае его нет, он использует конструктор класса объекта. После того, что метод
y.a();
называется. Такой метод не существует в классе Z, поэтому мы снова оказываемся в классе X, где существует метод a и выполняем его. Сначала мы выполняем метод Б, который, потому что ваш объект является экземпляром класса Z, а также метод б перезаписывается в классе Z приводит к выходу
b from class Z.
После того, что метод с называется (в методе а) , Так как наш экземпляр остается экземпляр из класса Z и существует метод с в этом классе вы можете прийти с идеей о том, что выход
c from class Z
будет происходить. Но это не так, потому что метод c в классе X является частным методом. Так как он частный, он не может быть унаследован подклассами (его даже не видно). Поэтому нет необходимости, чтобы любой класс, наследующий от X, также имел метод c. Верно ли, что из-за этого вызов c из метода a приводит к вызову метода c в классе X, а не в классе Z?
Итак, повторяю: Является ли мое объяснение сверху правильным или я что-то упускаю? Я просто немного смутило, что, хотя мой экземпляр из класса Z, вызвав метод с из внутри метод а приводит к следующему результату:
b from class Z
c from class X
Моя первая мысль была о том, что выход выглядит следующим образом:
b from class Z
c from class Z
Надеюсь, я описал проблему таким образом, чтобы кто-то мог мне помочь. Спасибо за все ответы.
Одна заметка: Вы говорите: «компилятор просматривает каждый суперкласс, есть ли конструктор». Все эти классы имеют конструкторы. Если в исходном коде нет ни одного, компилятор будет генерировать конструктор no-arg по умолчанию, который просто вызывает конструктор суперкласса. –