Страницы

Поиск по вопросам

понедельник, 19 ноября 2018 г.

Tricky inheritance (Хитрое наследование)

Итак, продолжим экскурс в Java-задачки. Очередная из тех же источников, правда, она может показаться весьма простой для бывалых или для тех, у кого под рукой компилятор. Код: public class A { public A() { myMethod(); } public void myMethod() { Date date = new Date(); } }
public class B extends A { private Date date = new Date();
public B() { date = new Date(); }
@Override public void myMethod() { System.out.println(date); }
//... public static void main(String[] args) { B sub = new B(); sub.myMethod(); } } Вопросы: Каков же вывод данной программы? Поясните свой предыдущий ответ Для изучающих ООП задачка будет весьма полезной. Кроме того, можете добавить свои соображения по поводу того, почему данная программа не является отказоустойчивой (robust).


Ответ

Признаюсь сразу, ответ получен с помощью компилятора. null Tue Oct 11 00:19:35 MSD 2011 Все дело в том, что вызываемый из конструктора A myMethod() оказывается одноименным методом конструктора B, а в это время поле date класса B еще не инициализировано датой. Понятно, что память выделена и обнулена. Вторая строчка вывода это ожидаемый результат вызова sub.myMethod() из main(). Порядок вызовов такой: конструктор A, из него метод myMethod() класса B (он переопределяет myMethod() класса A), конструктор B (инициализирует дату) и наконец sub.myMethod(); Локальный для класса A метод myMethod() вообще не вызывается. Директива @Override в данном случае никак себя не проявляет (сигнатуры одинаковы). Видимо это пример того, что не надо делать методы с одинаковыми именами (не только сигнатурами !), вызываемыми из конструкторов. Да, Java это язык, на котором элегантно пишутся головоломки.

Комментариев нет:

Отправить комментарий