Вкладений клас є членом класу, в який він вкладений. Внутрішні класи мають доступ до членів класу, в який вони вкладені, навіть якщо ці члени оголошені з модифікатором private. для цього компілятор створює спеціальні методи доступу до цих полів, так що сама віртуальна машина принципів ООП не порушує.
Як члени класу вкладені класи можуть бути оголошені з ключовим словом private. protected. public або без модифікатора доступу (package-private).
Зовнішній клас (OuterClass) може бути тільки public або package-private!
Для чого використовувати вкладені класи
Причини для використання вкладених класів в Java:
- Логічна угруповання класів, які використовуються тільки в одному місці. Якщо клас використовується тільки одним іншим класом, то є сенс вкласти його в цей клас, щоб позначити їх зв'язок.
- Збільшення інкапсуляції. Якщо клас B повинен звертатися до членів класу A. які в іншому випадку були б оголошені private. то має сенс вкласти клас B до класу A. тоді ці члени можна буде оголосити private. але B зможе до них звертатися. На додаток B можна буде приховати від зовнішнього світу.
- Полегшення читання та супроводу коду. Маленькі класи можна вкласти в зовнішні класи, ближче до місця використання.
Статичні вкладені класи
Статичні вкладені класи пов'язані зі своїм зовнішнім класом так само, як методи і змінні.
І так само як і статичні методи вони не можуть звертатися до змінних примірників і методам примірників зовнішнього класу, в який вони вкладені, безпосередньо, вони можуть звертатися до них тільки через посилання на об'єкт. Через посилання на об'єкт вони можуть звертатися до членів примірників зовнішнього класу незалежно від їх модифікатора доступу.
Статичні вкладені класи можуть звертатися до static членам класу, в який вони вкладені, з будь-яким модифікатором доступу.
Такі внутрішні класи зазвичай зазвичай логічно пов'язані зі своїм зовнішнім класом. Вони мають доступ до всіх полів цього зовнішнього класу. Примірники цих класів можуть створюватися усередині зовнішнього класу і, при достатньому рівні доступу, іншими класами з інших пакетів.
Нестатичні вкладені класи, які є членами класу, можуть бути оголошені з будь-яким з модифікаторів private. protected. public або без модифікатора (package-private).
локальні класи
Локальним класом називається клас, який не є членом будь-якого іншого класу і має ім'я.
Локальні класи не можу мати ніяких модифікаторів доступу: ні private. ні protected. ні public.
Вираз анонімного класу складається з:
- Операції new.
- Імені інтерфейсу для реалізації або батьківського класу. В даному прикладі використовується інтерфейс MyInterface.
- Дужки з аргументами для конструктора батьківського класу. Анонімний клас не може оголосити в своєму тілі нових конструкторів, так як у нього немає імені.
- Тіло класу.
Анонімний клас ніколи не може бути abstract (абстрактні класи будуть розглянуті пізніше).
Анонімний клас завжди неявно final.
Анонімні класи можуть звертатися до змінних методу, в якому вони оголошені, якщо ці змінні оголошені як final. або вони final за дією, тобто фактично не змінюються.
затінення змінних
Якщо ім'я змінної в будь-якій області має таке ж ім'я, що і змінна у зовнішній області, то така змінна затінює (shadow) змінну із зовнішнього області. Ви не можете звернутися до змінної з зовнішньої області просто по імені. Приклад нижче показує, як потрібно звертатися до затіненій змінної:
У цьому прикладі параметр x методу method1 затінює член класу SecondInnerClass. а x з SecondInnerClass затінює x з FirstInnerClass. а x з FirstInnerClass закриває x з ShadowClass відповідно.
Зверніть увагу на звернення до x з різних рівнів вкладеності класів (x. This. X. SecondInnerClass. This. X).
Лямбда-вирази
Найчастіше анонімний клас реалізує інтерфейс, який містить тільки один абстрактний метод. В цьому випадку код можна написати ще більш коротко і зрозуміло, якщо використовувати лямбда-вирази.
Інтерфейс, який містить тільки один абстрактний метод, називається функціональним інтерфейсом. Функціональний інтерфейс може також містити будь-яку кількість статичних методів і default методів. Більш докладно інтерфейси будуть розібрані у відповідній статті.
Лямбда-вираз складається з:
- Списку формальних параметрів, розділених комою і ув'язнених в дужки. Якщо формальний параметр тільки один, то дужки можна опустити. Якщо формальних параметрів немає, то використовуються просто порожні дужки. Тип формальних операторів вказувати можна, але не обов'язково.
- Токен стрілки ->.
- Тіло, що складаються з одного оператора / інструкції або з блоку операторів / інструкцій. У разі блоку операторів і результату методу відмінного від void для повернення значення використовується ключове слово return. У разі одного виразу результатом лямбда-вирази є результат цього виразу. Блок операторів може бути порожнім.
Те буде помилка компіляції, так як змінна x в цій області вже оголошена.
Тип результату у лямбда-вирази буде такою, якою очікується в цьому місці, тому лямбда-вирази можна використовувати тільки там, де компілятор Java може визначити його тип:
Лямбда-вирази можна серіалізовать, якщо його аргументи і результат Серіалізуемое, проте так робити строго НЕ рекомендується.
Деякі з функціональних інтерфейсів пакета java. util. function:
Consumer
Function
Predicate
Supplier
Посилання на методи
Якщо лямбда-вираз виконує тільки виклик певного методу або конструктора, то замість нього можна використовувати посилання на метод.
Коли використовувати вкладені класи, локальні класи, анонімні класи і лямбда-вирази
Використовуйте локальні класи. якщо ви збираєтеся створювати більш одного екземпляра класу, використовувати конструктор або збираєтеся вводити новий іменований тип.
Використовуйте анонімні класи. якщо вам потрібно додавати поля або додаткові методи.
Використовуйте лямбда-вирази. якщо вам потрібен один екземпляр функціонального інтерфейсу, або якщо ви збираєтеся передавати одну дію в інший метод, наприклад обробник події.
Використовуйте вкладений клас. якщо у вас такі ж вимоги, як і для локального класу, але ви хочете зробити його більш широко доступним. Якщо вам потрібен доступ до змінних зовнішнього класу, то використовуйте нестатичних вкладений клас (внутрішній клас), в іншому випадку використовуйте статичний вкладений клас.
Ще записи з цієї рубрики:
Багато, складно, але посильно. Тільки чи варто на цьому зациклюватися початківцю або краще повернуться сюди потім? (Добре знаю AsctionScript 3)
=
Ще один момент: я читав, що внутрішні класи тісно пов'язані з подіями в Java. А в цьому розділі про це ні слова. Та й взагалі в списку статей про Java немає такої статті «Java 8 події».
Хоча може я щось не правильно зрозумів.