Найти в Дзене
yagdmitrij

Внутренние и анонимные классы в Java: тонкости применения

В языке java классы могут быть не только самостоятельными сущностями — их можно определять внутри других классов. Такие конструкции называются вложенными классами и делятся на две ключевые категории: статические вложенные классы и внутренние классы. Особой разновидностью внутренних классов выступают анонимные классы Java. Разберёмся, чем они отличаются и как эффективно их использовать. Внутренний класс — это нестатический вложенный класс, объявленный внутри другого класса. Он имеет прямой доступ ко всем членам внешнего класса (включая приватные), поскольку логически «привязан» к экземпляру внешнего класса. Ключевые особенности: · Может быть объявлен с модификаторами private, protected, public или с доступом в пределах пакета. · Для создания экземпляра требуется объект внешнего класса: · Имеет доступ к полям и методам внешнего класса, даже если они private. Интересно посмотреть, как строится объект внутреннего класса: Итак, чтобы создать объект внутреннего класса, должен присутствовать
Оглавление
java
java

В языке java классы могут быть не только самостоятельными сущностями — их можно определять внутри других классов. Такие конструкции называются вложенными классами и делятся на две ключевые категории: статические вложенные классы и внутренние классы. Особой разновидностью внутренних классов выступают анонимные классы Java. Разберёмся, чем они отличаются и как эффективно их использовать.

Внутренний класс — это нестатический вложенный класс, объявленный внутри другого класса. Он имеет прямой доступ ко всем членам внешнего класса (включая приватные), поскольку логически «привязан» к экземпляру внешнего класса.

Ключевые особенности:

· Может быть объявлен с модификаторами private, protected, public или с доступом в пределах пакета.

· Для создания экземпляра требуется объект внешнего класса:

· Имеет доступ к полям и методам внешнего класса, даже если они private.

Интересно посмотреть, как строится объект внутреннего класса:

внутренний класс
внутренний класс

Итак, чтобы создать объект внутреннего класса, должен присутствовать созданный объект внешнего класса, так как между ними существует некоторая тайная связь, понятная только Великому Компилятору). Для нас не важно, как происходит взаимодействие между объектами, важно понять сам смысл построения объекта внутреннего класса. Что мы видим в вышеприведенном коде? Внутренний класc Vnutri легко оперирует приватным членом внешнего класса Vneshnij, что нельзя сказать в обратном направлении, так как это логично для java. Что еще. Мы видим несколько вариантов построения внутреннего класса. Первый вариант предполагает, что внутренний объект строится не в самом внешнем классе, включая метод main, как в нашем случае. Построение будет происходить по такому принцип: имя_внешнего_класса.имя_внутреннего_класса = объект_внешнего_класса.new имя_внутреннего_класса().

внутренний класс
внутренний класс

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

Локальные классы

Внутренние классы также могут создаваться внутри самих методов. И такие классы называются - внутренними локальными классами, которые скрыты даже от самих внешних классов. О нем не знает никто, кроме метода в котором такой класс создан.

Попробуем создать локальный внутренний класс и обратиться к нему.

локальный класс
локальный класс

Как видим, это невозможно. Однако если наш внутренний класс будет реализовывать некий интерфейс, то ссылку на этот интерфейс мы получим и соответственно к его реализованным методам. Это будет более понятно после изучения интерфейсов.

Есть еще одна особенность локальных внутренних классов. Как мы знаем, что они имеют доступ к членам внешнего класса, а вот к локальным членам - только к тем, которые final, или «эффективно финальные», т.е. неизменяемые в коде.

Рассмотрим. Здесь показан доступ из локального класса к разным переменным.

локальный класс
локальный класс

Анонимные классы

Теперь о анонимных классах. Здесь еще все запутаннее и непонятно.

Анонимный класс java — это особый вид внутреннего класса, который:

  • Не имеет имени;
  • Объявляется и создаётся одновременно;
  • Может расширять класс или реализовывать интерфейс;
  • Не допускает объявления конструкторов (так как у него нет имени);
  • Имеет доступ к final или «эффективно финальным» локальным переменным окружающего контекста.

Ограничения анонимных классов:

· Нельзя объявлять статические поля/методы (кроме констант static final).

· Нельзя реализовывать несколько интерфейсов одновременно.

· Нельзя расширять класс и реализовывать интерфейс в одном объявлении.

· Доступ к локальным переменным только если они final или «эффективно финальные».

Выбирать анонимные классы нужно, если класс нужен только один раз или реализация занимает несколько строк.

Рассмотрим все на примерах:

анонимный класс
анонимный класс

Еще раз. Анонимный класс не имеет имени, поэтому у него не будет и конструкторов. Предполагается, что он наследуется от какого-то класса, в нашем случае это Pervij, либо реализует интерфейс Inter. Интерфейс будет поинтереснее, так как мы можем получить доступ к членам анонимного класса через реализованные методы… Хотя, если использовать абстрактный класс в качестве наследника, который предполагает, что его методы тоже будет обязан реализовать анонимный класс.

Все это настолько запутано, что, изучая это в первый раз, даже плакать хочется(. Давайте еще раз посмотрим, как создается объект обычного класса и анонимного.

создание объекта обычного класса:

Pervij per=new Pervij();

создание объекта анонимного класса:

Pervij per=new Pervij() {тело анонимного класса, который расширяет класс Pervij};

Статические вложенные классы

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

Давайте это рассмотрим:

анонимные классы
анонимные классы

Внутренние и анонимные классы java – мощные инструменты для: инкапсуляции логики внутри класса, сокращения кода при работе с интерфейсами и создания «легких» реализаций без объявления отдельных типов. Главное – соблюдать баланс: анонимные классы удобны для простых случаев, а внутренние классы лучше подходят для сложной, повторно используемой логики. Понимание их особенностей позволяет писать более чистый и эффективный код.

Ставьте лайки, подписывайтесь на канал и вас ждет масса интересных статей по программированию.

моя телега