Размер шрифта:
Уровень 24. Ответы на вопросы к собеседованию по теме уровня
Play

Уровень 24. Ответы на вопросы к собеседованию по теме уровня

Анонимные внутренние классы компилируются в файлы внешнийКласс$n.class . На месте внешнего класса, соответственно, название обрамляющего класса, внутри которого описывается анонимный внутренний класс. На месте n число от 1 до количества анонимных классов.

Можно ли наследовать внутренние классы?

Наследовать внутренние классы от других — можно.

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

Здесь класс InheritInner расширяет только внутренний класс, а не внешний. Но когда дело доходит до создания конструктора, предлагаемый по умолчанию конструктор не подходит, и вы не можете просто передать ссылку на внешний объект. Необходимо включить в тело конструктора выражение ссылкаНаОбъемлющийКласс.super(); в теле конструктора. Оно обеспечит недостающую ссылку, и программа откомпилируется.

Можно ли наследовать анонимные внутренние классы?

Описывая анонимный класс мы уже наследуемся от какого-то класса или реализуем какой-либо интерфейс. К анонимным классам напрямую нельзя применить слова extends или implements, но ведь никто не мешает заранее подготовиться и расширить нужный интерфейс, который будем реализовывать с помощью анонимного класса. Пример в коде ниже.

Наследоваться от анонимного класса нельзя.

Можно ли переопределять внутренние классы?

Переопределение внутреннего класса, как если бы он был еще одним методом внешнего класса, фактически не имеет никакого эффекта:

Вывод:

Конструктор по умолчанию автоматически синтезируется компилятором, а в нем вызывается конструктор по умолчанию из базового класса. Можно подумать, что при создании объекта BigEgg должен использоваться «переопределенный» класс Yolk , но это отнюдь не так, как видно из результата работы программы.

Этот пример просто показывает, что при наследовании от внешнего класса ничего особенного с внутренними классами не происходит. Два внутренних класса — совершенно отдельные составляющие, с независимыми пространствами имен. Иными словами нельзя.

Какие ограничения есть у локальных классов?

Вначале вспомним что такое локальный класс. Это класс, описанный в блоке кода, то есть, по-простому — между кавычек . Наиболее часто эти кавычки являются телом метода. Но могут они быть и просто блоком, статическим блоком, телом if -ов, циклов и т.д.

Локальный класс наделён особенностями внутренних классов, но имеет отличительные черты, а именно:

  1. он имеет доступ только к финальным полям и аргументам обрамляющего метода, а также ко всем полям обрамляющего класса, в том числе приватным и статическим;
  2. локальный класс виден и может создаваться только в блоке, в котором описан;
  3. у локального класса не ставится модификатор доступа;
  4. не может иметь статических полей, методов, классов (за исключением финальных);
  5. локальный класс, объявленный в статическом блоке может обращаться только к статическим полям внешнего класса.

Но! Начиная с Java8 мы можем обращаться в локальных классах к не финальным локальным переменным, если они не были изменены до момента инициализации класса. Также теперь стало возможным обращение к не финальным параметрам метода.

Может ли анонимный внутренний класс содержать статические методы?

Нет. У Анонимных внутренних классов, как и у внутренних классов не может быть статических полей, методов. (вспомним, что анонимные классы компилируются в обычные внутренние, а те, в свою очередь, связаны с объектом обрамляющего класса)

Можно ли создать объект внутреннего класса, если у внешнего класса только private конструктор?

Имея подобный код:

Напрямую, в другом классе (вне обрамляющего), конечно, создать объект InnerClass следующим способом не получится:

Но! Что если у нас есть метод, возвращающий экземпляр

В этом случае приватный конструктор нам не помеха для создания объекта InnerClass . Так же мы без проблем сможем создавать его в методах и в других внутренних классах, принадлежащих PrivateConst . Ответ — можно, если каким-либо способом нам удастся получить объект обрамляющего класса.

Можно ли объявлять внутренние классы private ?

PS Обоснования так и не нашел, но на философии java встречались подобные примеры. Плюс IDE не ругается. Буду признателен за обоснование, но предположу, что в этом плане внутренний класс ничем не отличается от обычного класса.

Можно ли объявлять анонимные внутренние классы private ?

Аналогично (в плане не нашел обоснования). Можно объявить private переменную от типа которой наследуется наш анонимный класс.

Сколько у класса максимально может быть внутренних классов?

📎📎📎📎📎📎📎📎📎📎