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

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

Внутренний класс можно создавать с любым уровнем доступа: private, protected, public, пакетная видимость. Его члены также могут иметь любой из уровней доступов.
Внутренний класс не может содержать статические методы. Он может содержать final static поля, но просто static-поля - нет.


class Outer {

    protected class Inner {

        Inner() { } // конструктор
        public String a = "Inner";
        private int b = 20;
        final static float c = 15.5F;
        static int staticInner = 10; // ошибка компиляции

        static void staticMethod() { } // ошибка компиляции
    }
}
Объект внутреннего класса не может существовать без объекта внешнего.
Объект внутреннего класса можно создать внутри внешнего класса, внутри его статического или экземплярного метода.


class Outer {

   class Inner { }

     // внутри класса
     Inner objectInner = new Inner();

    // внутри метода экземпляра
    void instanceMethod() {
        Inner objectInner = new Inner();
    }

    // внутри статического метода
    static void staticMethod() {
        Outer outObj = new Outer();
        Inner innerObj = outObj.new Inner();
        // другой способ создания объекта внутреннего класса:
        Inner innerObj2 = new Outer().new Inner();
    }
}
Чтобы создать объект внутреннего класса извне, сначала нужно создать экземпляр внешнего класса. При этом тип переменной в качестве префикса должен иметь имя внешнего класса.


class AnotherClass {

    Outer.Inner var;

    AnotherClass() {
        Outer outer = new Outer();
        var = outer.new Inner();
    }
}
Внутренний класс является частью внешнего, поэтому он имеет доступ ко всем членам внешнего класса, включая приватные и унаследованные от родительских классов.


class Parent {

    protected String parent = "Parent";
}

class Outer extends Parent {

    private String outer = "Outer";
    static int number = 20;

    class Inner {

        String publicInner = Outer.this.outer;
        int sameName = Outer.number;

        void innerMethod() {
            System.out.println(Outer.this.parent);
        }
    }
}
Типы данных