Переопределение переменных в дочерних классах

210
28 мая 2022, 01:20

Насколько я понял, в объекте a будут доступны только те переменные и методы, которые есть в классе A, но запускаться они будут из класса B. Но вот рассмотрим код:

class A {
    int test1 = 11;
    int test2() { return 12; }
    static int test3() { return 13; }
}
class B extends A {
    int test1 = 31;
}
class C extends B {
    int test1 = 21;
    int test2() { return 22; }
    static int test3() { return 23; }
}
class Test {
    public static void main(String[] args) {
        A a1 = new A();
        System.out.println(a1.test1);   //1.
        System.out.println(a1.test2()); //2.
        System.out.println(a1.test3()); //3.
        A a2 = new C();
        System.out.println(a2.test1);   //4.
        System.out.println(a2.test2()); //5.
        System.out.println(a2.test3()); //6.
        a1 = null;
        System.out.println(a1.test3()); //7.
        System.out.println(a1.test2()); //8.
        System.out.println(a1.test1);   //9.
    }
}

Как объяснить то, что в 4 пункте выводит 11? Эта переменная же в классе C имеет значение 21.

Answer 1

Прошёлся дебагером по вашему коду:

  1. Создаётся объект класса A. Переменной test1 присваивается значение 11. Выводится 11.
  2. Выполняется метод test2() на объекте класса A. Выводится 12.
  3. Выполняется статический метод test3() класса A. Выводится 13.
  4. Создается объект класса C и помещается в переменную класса A. Поскольку поле test1 берётся у переменной класса A, то выводится 11.
  5. Выполняется метод test2() на объекте класса C. Выводится 22.
  6. Выполняется статический метод test3() класса A. Выводится 13.
  7. Переменной a1 класса A присваивается значение null. Выполняется статический метод test3() класса A. Выводится 13.
  8. Выполняется метод test2() на объекте класса A, но этот объект равен null. Выводится NullPointerException. Выполнение кода прерывается.
  9. До строки 9 мы не дошли, но если бы в ней был вызов метода test1() на объекте класса A, тогда бы мы получили ошибку компиляции, т. к. test1 - это поле класса A, а не его метод. Если бы метод test1() существовал, тогда бы мы получили NullPointerException, т. к. объект класса A равен null.

Вызов статического метода на объекте класса при компиляции заменяется на вызов метода самого класса, поэтому мы не получаем NullPointerException в случае, если объект класса равен null.

См. дополнительно: Порядок инициализации объектов в Java.

Answer 2

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

READ ALSO
java наследование и private

java наследование и private

Есть 2 класса,КлассА и КлассБ ClassAjava->

165
Как получить номер фискального регистратора ШТРИХ-М-02Ф?

Как получить номер фискального регистратора ШТРИХ-М-02Ф?

Мне нужно программно получить полный номер фискального регистратора(ФР), я использую метод getPhysicalDeviceName:

123
Кнопка back не работает WebView

Кнопка back не работает WebView

Необходимо сделать, чтобы при нажатии кнопки Back на телефоне приложение не закрывалосьНашел код на форуме, вроде бы расставил все куда нужно,...

211
Отсутствует доступ к сервлету

Отсутствует доступ к сервлету

Изучаю тему сервлетовСтолкнулся с такой проблемой, что html и jsp работают, однако когда я пытаюсь зайти на страницу сервлета (адрес http://localhost:8080/SE/hello),...

116