Главная » Java » Расширение внутренних классов Java

0

Внутренние классы допускают расширение – точно так же, как и любые статические вложенные классы и обычные классы "верхнего" уровня. Единственное требование состоит в том, что объекты расширенного класса должны сохранять связь с объектами исходного внешнего класса или класса, производного от него. Обычно обеспечить выполнение такого требования несложно, поскольку расширенный вложенный класс часто объявляется внутри расширенного внешнего класса

 

Поле ref инициализируется при создании объекта класса ExtendedOuter. В ходе процесса построения экземпляра класса ExtendedInner вызывается его конструктор по умолчанию без параметров, который, в свою очередь, посредством ссылки super неявно обращается к конструктору по умолчанию класса Inner. Конструктор Inner требует наличия объекта Outer, к которому следует "привязаться", – в этой роли выступает текущий объект класса ExtendedOuter.

Если внешним по отношению к расширенному внутреннему классу служит другой класс, не производный от Oute г, либо если внутренний класс в результате расширения перестает быть внутренним, для обеспечения корректности вызова конструктора класса Inner с помощью ссылки super должна быть предоставлена дополнительная явная Ссылка на объект Outeг. Приведем пример, иллюстрирующий сказанное:

class Unrеlated extends Outer.Inner { Unrеlated(outer ref) {

ref. super() ;

}

}

Когда процесс конструирования объекта класса Unrеlated достигает точки вызова конструктора базового класса, должна существовать ссылка на объект класса outeг, к которому можно было бы привязать объект базового класса. Unrеlated сам по себе не является внутренним классом класса Outer, поэтому в данном случае неявный внешний объект отсутствует. Аналогично, поскольку Unrеlated не относится к числу классов, производных от Outer, текущий объекТ Unrеlated не будет правильным внешним объектом. Нам надлежит обеспечить явную ссылку на объект Outer, к которому удастся привязать объект базового класса. Мы остановили выбор на способе передачи ссылки в виде аргумента конструктора класса Unrеlated. Этот конструктор использует ее как явную связывающую ссылку при вызове конструктора базового класса.

Обратите внимание на то, что нельзя пользоваться синтаксисом построения объекта внутреннего класса для создания требуемого объекта Outer "внешним образом":

Outer ref = new Outer();

Unrеlated u = ref.new Unrеlated(); // НЕВЕРНО!

"Указанный код предполагает создание внешнего объекта для класса Unrеlated, но Unrеlated не является внутренним классом.

Один внутренний класс способен наследовать другой, никак с ним не связанный, внутренний класс, как только что было показано. Объект внутреннего класса, полученного таким образом, будет обладать двумя внешними объектами: одним, отвечающим расширенному классу, и другим, относящимся к базовому классу. Подобные решения, конечно, довольно извилисты и сложны, а поэтому лучше их избегать.

 

Источник: Арнолд, Кен, Гослинг, Джеймс, Холмс, Дэвид. Язык программирования Java. 3-е изд .. : Пер. с англ. – М. : Издательский дом «Вильяме», 2001. – 624 с. : ил. – Парал. тит. англ.

По теме:

  • Комментарии