Назад Зміст Вперед

11.1 Регулярні внутрішні класи

У мові jаvа допускається визначати один клас в іншому класі. такі класи називаються вкладеними. Область дії вкладеного класу обмежена областю дії зовнішнього класу. Так, якщо клас В визначено в класі А, то клас В не може існувати незалежно від класу А. Вкладений клас має доступ до членів (в тому числі закритим) того класу, в який він вкладений. але зовнішній клас не має доступу до членів вкладеного класу. Вкладений клас, оголошений безпосередньо в області дії свого зовнішнього класу, вважається його членом. Можна також оголошувати вкладені класи, які є локальними для блоку коду. 
Існують два типи вкладених класів: статичні та нестатичні.

Статичним називається такий вкладений клас, який оголошується з модифікатором statiс. А оскільки він є статичним, то повинен звертатися до нестатичних членів свого зовнішнього класу за допомогою об'єкта. Це означає, що вкладений статичний клас не може безпосередньо посилатися на нестатичні члени свого зовнішнього класу. 

Найбільш важливим типом вкладеного класу є внутрішній клас. 
Внутрішній клас - це нестатичний вкладений клас. Він має доступ до всіх змінних і методів свого зовнішнього класу і може безпосередньо посилатися на них таким же чином, як це роблять інші члени нестатичного зовнішнього класу.

У наведеному нижче прикладі програми демонструється визначення і використання внутрішнього класу. У класі Outer міститься одна змінна екземпляра outer_x , один метод примірника test ( ) і визначається один внутрішній клас Inner.
class Outer {
int outer_х 100;
void test( )
Inner inner = new Inner( );
inner.display( ) ;

//це внутрішній клас
class Inner{
void display( ){
System.out.println  "вивід: outer х " + outer_x ) ;


class Inner ClassDemo {
puвlic static void main ( String args [ ] ) {
Outer outer = new Outer ( );
outer.test( );


Результат:
outer_x = 100

У даній програмі внутрішній клас Inner визначено в області дії класу Outer . Тому будь-який код з класу Inner може безпосередньо звертатися до змінної outer_ х. Метод примірника display ( ) визначений у класі Inner. Цей метод виводить значення змінної outer_x в стандартний потік виведення. В методі main ( ) класу InnerClassDemo створюється екземпляр класу Outer і викликається його метод test( ). А в цьому методі створюється екземпляр класу Inner і викликається метод display ( ). Слід мати на увазі, що екземпляр класу Inner може бути створений тільки у контексті класу Outer. В іншому випадку компілятор Java видасть повідомлення про помилку.

Внутрішні класи 

представляють такі типи, які визначені всередині інших класів. Наприклад, є клас Book, всередині якого визначено клас Publisher:

class Book{
    String name;
    String author;
    int year;
    public Publisher publisher;
    Book(String name, String author, int year, String publ){
         
        this.name = name;
        this.author = author;
        this.year = year;
        publisher = new Publisher(publ);
    }
     
    class Publisher{
     
        public String name;
        public Book book;
         
        public Publisher(String name){
            book=Book.this;
            this.name=name;
        }
    }
}

Внутрішній клас поводиться як звичайний клас за тим винятком, що його об'єкти можуть бути створені тільки всередині зовнішнього класу.

Внутрішній клас має доступ до всіх полів зовнішнього класу, в тому числі закритих, за допомогою модифікатора private. А саме посилання на зовнішній клас з внутрішнього можна отримати за допомогою виразу Book.this, де спочатку йде ім'я зовнішнього класу.

Тепер використовуємо класи:

Book b1 = new Book("Война и мир", "Л. Н. Толстой", 1863, "ХудКнига");
System.out.println(b1.publisher.name);

Об'єкти внутрішніх класів можуть бути створені тільки в тому класі, в якому внутрішні класи визначені. В інших зовнішніх класах об'єкти внутрішнього класу створити не можна.
Ще однією особливостей внутрішніх класів є те, що їх можна оголосити всередині будь-якого контексту, в тому числі всередині методу і навіть в циклі:

class Book{
    String name;
    String author;
    int year;
    Book(String name, String author, int year){
         
        this.name = name;
        this.author = author;
        this.year = year;
    }
    public void setPublisher(String publ){
     
        class Publisher{
            void displayInfo(){
                System.out.println("Издатель: " + publ);
            }
        }
         
        Publisher publisher = new Publisher();
        publisher.displayInfo();
    }
}

Потім при використанні нам досить викликати метод set Publisher об'єкта Book:\
Book b1 = new Book("Война и мир", "Л. Н. Толстой", 1863);
b1.setPublisher("ООО ХудКнига");

Отже,

У літературі по Java зустрічаються такі терміни, як "внутрішні класи" (inner classes) і "вкладені класи" (nested classes). Говорити ми будемо про вкладені класи, для яких inner класи є підмножиною. Проте часто під внутрішніми класами маються на увазі всі вкладені.

Отже, вкладений клас - це клас, який оголошений всередині оголошення іншого класу. Наприклад:
class OuterClass {
...
static class StaticNestedClass {
...
}
...

ЧИМ ВІДРІЗНЯЮТЬСЯ ВКЛАДЕНІ КЛАСИ ВІД ВНУТРІШНІХ. Внутрішній клас - це різновид вкладеного класу, а саме: внутрішній клас - це нестатичний вкладений клас. Екземпляр внутрішнього класу отримує посилання на екземпляр зовнішнього, екземпляр статичного вкладеного класу - ні.

Вкладені класи діляться на статичні (в прикладі вище StaticNestedClass - це саме він) і нестатичні (non-static). Власне нестатичні вкладені класи мають й іншу назву - внутрішні класи (inner classes). Зовнішній клас (outer class) називають ще класом-обгорткою.


Вбудовані класи Java

Тип класуОпис


Класи та інтерфейси верхнього рівня
Клас або інтерфейс, який є членом пакетаЗвичайний клас або інтерфейс, який є безпосереднім членом пакета і основним класом Java, який розуміє віртуальна машина. До цього типу перетворюються всі вбудовані або внутрішні класи.
Вкладений клас або інтерфейс верхнього рівняВкладений клас або інтерфейс, який повинен бути оголошений як static всередині іншого класу або інтерфейсу верхнього рівня (вкладені інтерфейси завжди неявно оголошені як static). Можуть використовувати статичні члени класу, в якому вони містяться.






Вбудовані класи
Клас-членКлас, певний як член (НЕ-static) іншого класу. Кожному екземпляру такого класу відповідає екземпляр зовнішнього класу, причому перший може використовувати члени другого. Для класів даного типу введений новий синтаксис операторів this, new і super. Клас-член не може мати статичних членів, а його ім'я не повинно збігатися з іменем зовнішнього класу.
Локальний класКлас, який визначений в будь-якому програмному блоці і який може використовувати члени зовнішнього класу, а також локальні змінні і параметри з модифікатором final. Для класів даного типу введений новий синтаксис оператора this. Використовуються ті ж обмеження, що і для класів-членів.
Анонімний класКлас без імені, який визначається в вираженні і має властивості локального класу. Дозволяє визначити клас одноразового використання в тому місці програми, де це необхідно. Використовуються ті ж обмеження, що і для локального класу, плюс відсутність імені та конструктора. Може бути створений лише один екземпляр такого класу.





http://metanit.com/java/tutorial/3.12.php
http://easy-code.ru/lesson/local-anonymous-nested-classes-java
http://pr0java.blogspot.com/2015/08/3-inner-classes.html
.