Вложенные классы (Nested classes)

РЕЗЮМЕ: Вложенный класс – это член класса, как метод или поле класса, со всеми вытекающими последствиями. Статический вложенный ведёт себя подобно статическому методу, а не статический(внутренний) подобно обычному методу.

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

Вложенные классы делятся на статические и нестатические. Нестатические вложенные классы называются внутренними.

Зачем нужны вложенные классы(из документации):

1) Если один из связанных по смыслу классов, полезен только для этого одного класса, логично связать их тесно таким образом. Такой подход организации кода поможет не создавать “лишних” классов в структуре пакета, и сделает пакет более удобочитаемым и прямолинейным.
2) Для усиления инкапсуляции, чтобы можно было получить доступ к private-полям: Представим, что есть два класса: A и B, и в A мы должны сохранять многие поля private, но в то же время в B нам нужны эти поля. В добавок, нам, к примеру, нужно спрятать логику B.
3) Если просто для наглядности нам нужно разместить тот код, который используется ближе к тому месту где он используется.

Статический вложенный класс (Static Nested Class)

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

К примеру, чтобы создать объект этого класса, используем синтаксис:

Внутренний класс (Inner Class)

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

Экземпляр InnerClass может существовать только внутри экземпляра OuterClass и имеет прямой доступ к методам и полям класса -оболочки. Чтобы создать экземпляр внутреннего класса, сначала нужно создать класс-оболочку. Затем, внутри внешнего класса можно создать объект следующим образом:

Существует два вида внутренних классов – локальные и анонимные (local, anonymous)

Затенение(shadowing)

Если объявленный тип тип переменной (переменная члена или имя параметра) в определенном блоке(таком как внутренний класс или определение метода) имеет такое же имя, что и другая переменная в классе оболочке, то эта новая переменная затеняет переменную из оболочки, таким образом что затененная переменная внешнего класса оказывается недоступной. Например:

Вывод:
x = 23
this.x = 1
ShadowTest.this.x = 0
В примере есть три переменных, – поле внешнего класса, поле внутреннего класса, и параметр метода. Параметр метода затеняет то что есть во внутреннем классе, в свою очередь, то что есть во внутреннем классе затеняет переменную внешнего.
Как и обычно, чтобы добраться до переменной экземпляра, нам нужно использовать this:

Чтобы дать понять java какой из this классов нам нужен, нам следует уточнить this названием класса как показано ниже:

сериализация

сериализация внутренних классов подразумевает создание конструктов, которые никак не согласуются с синтаксисом исходного кода. Синтетические конструкты java позволяют компиляторам внедрять различные новшества в язык без изменения java-машины. Однако, синтетические конструкты могут отличаться в разных компиляторах java. Как следствие можно получить некоторые проблемы при сериализации внутренних классов в одном JRE и десериализации в другом.

ВНИМАНИЕ

Только вложенный класс может быть static
Создать экземпляр статического вложенного класса возможно! (как и внутреннего), он существует благодаря тому, что его класс-носитель представляет из себя экземпляр.

примеры применения

Использование перечисления во вложенном классе

LEAVE A COMMENT