Вложенные и внутренние классы Java

Вложенные и внутренние классы JavaВ языке Java определены вложенные классы. Вложенным называется такой класс, который объявляется в другом классе.

Вложенные классы не относятся к базовым языковым средствам Java. Они даже не поддерживались до появления версии Java 1.1, хотя с тех пор часто применяются в реальных программах, и поэтому о них нужно знать.

Вложенный класс не может существовать независимо от класса, в который он вло­жен. Следовательно, область действия вложенного класса ограничена его внешним классом. Если вложенный класс объявлен в пределах области действия внешнего класса, то он становится членом последнего. Имеется также возможность объявить вложенный класс, который станет локальным в пределах блока.

Существуют два типа вложенных классов. Одни вложенные классы объявляются с помощью модификатора доступа static, а другие - без него. Классы такого типа называются внутренними. Внутренний класс имеет доступ ко всем переменным и мето­дам внешнего класса, в который он вложен, и может обращаться к ним непосредствен­но, как и все остальные нестатические члены внешнего класса.

Иногда внутренний класс используется для предоставления ряда услуг внешнему клас­су, в котором он содержится. Ниже приведен пример применения внутреннего класса для вычисления различных значений, которые используются включающим его классом.

//   

class Outer {

    int nums[];

    Outer(int n[]) {
        nums = n;
    }

    void Analyze() {
        Inner inOb = new Inner();
        System.out.println(": " + inOb.min());
        System.out.println(": " + inOb.max());
        System.out.println(": " + inOb.avg());
    }

//  

    class Inner {
        int min() {
            int m = nums[0];

            for(int i = 1; i < nums.length; i++) {
                if(nums[i] < m) m = nums[i];
            }
 
            return m;
        }

        int max() {
            int m = nums[0];

            for(int i = 1; i < nums.length; i++) {
                if(nums[i] > m) m = nums[i];
            }
 
            return m;
        }
 
        int avg() {
            int a = 0;
  
            for(int i = 1; i < nums.length; i++) {
                a += nums[i];
            }
 
            return a / nums.length;
        }
    }
}

class NestedClassDemo {
    public static void main(String args[]) {
        int x[] = {1, 2, 3, 5, 6, 7, 8, 9};
        Outer outOb = new Outer(x);
        outOb.Analyze();
    }
}

Результат выполнения данной программы выглядит следующим образом.

: 1
: 9
: 5

В данном примере внутренний класс Inner обрабатывает массив nums, являющий­ся членом класса Outer.

Вложенный класс имеет доступ к членам объемлющего клас­са, и поэтому он может непосредственно обращаться к массиву nums. А вот обратное несправедливо. Так, например, метод Analyze() не может непосредственно вызвать метод min() , не создав объект типа Inner.

Класс можно вложить в области действия блока. В итоге полу­чается локальный класс, недоступный за пределами блока. В следующем примере про­граммы мы преобразуем класс ShowBits, таким образом, чтобы он стал локальным.

//   ShowBits    

class LocalClassDemo {

    public static void main(String args[]) {

        //    ShowBits
        //  ,     main
        class ShowBits {
            int numbits;
        
            ShowBits(int n) {
                numbits = n;
            }

            void show(long val) {
                long mask = 1;

                //        

                mask <<= numbits - 1;

                int spacer = 0;
                for(; mask != 0; mask >>>=1) {
                    if((val & mask) != 0) System.out.print("1");
                    else System.out.print("0");
                    spacer++;
                    if((spacer % 8) == 0) {
                        System.out.print(" ");
                        spacer = 0;
                    }
                }
                System.out.println();
            }
        }

        for(byte b = 0; b < 10; b++) {
            ShowBits byteval = new ShowBits(8);
          
            System.out.print(b + "   : ");
            byteval.show(b);
        }

    }

}

Выполнение этой программы дает следующий результат.

0   : 00000000
1   : 00000001
2   : 00000010
3   : 00000011
4   : 00000100
5   : 00000101
6   : 00000110
7   : 00000111
8   : 00001000
9   : 00001001

В данном примере класс ShowBits недоступен за пределами метода main(), а следо­вательно, попытка получить доступ к нему из любого метода, кроме main(), приведет к ошибке.

И последнее замечание: внутренний класс может быть безымянным. Экземпляр безымянного, или анонимного, внутреннего класса создается при объявлении класса с по­мощью оператора new.

Чем же статический вложенный класс отличается от нестатического в языке программирования Java?

Статический вложенный класс объявляется с помощью модификатора static. Являясь статическим, он может непосредственно обращаться к любому статическому члену своего внешнего класса. Другие члены внешнего класса до­ступны ему посредством ссылки на объект.

Интересное видео для наших постоянных читателей:

Один комментарий на “Вложенные и внутренние классы Java

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *