Страницы

Поиск по вопросам

воскресенье, 8 декабря 2019 г.

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

#java #ооп


Внутренние и вложенные классы — это не одно и тоже.

В чем разница, и когда принципиально нужно использовать один, а когда другой?
    


Ответы

Ответ 1



Статические вложенные классы, не имеют доступа к нестатическим полям и методам обрамляющего класса. Поведение точно такое же, как у статических методов класса. Доступ к нестатическим полям и методам может осуществляться только через ссылку на экземпляр обрамляющего класса. Но static nested классы имеют доступ к любым статическим методам внешнего класса, в том числе и к приватным. public class Mememe { private static int m_AccessableInt; // доступно в StaticNestedMememe private int m_NotAccessableInt; // не доступно в StaticNestedMememe [...] public static class StaticNestedMememe { [...] } } Применение? Например, если вложенный класс имеет смысл только в контексте обрамляющего класса. Так же многие используют такие классы для реализации паттерна Builder. Экземпляр такого класса нужно создавать, используя имя обрамляющего класса: Mememe.StaticNestedMememe nestedObject = new Mememe.StaticNestedMememe(); Внутренние классы бывают трёх типов: локальные классы (local classes); анонимные классы (anonymous classes); внутренние классы-члены (member inner classes). Локальные классы определяются внутри блока кода. public class Mememe { public void calc(String requestPath) { class Сalculator{ int calc() { return 0; } } } } Локальные классы имеют доступ к полям и методам обрамляющего класса. Локальные классы: видны только в пределах блока, в котором объявлены; не могут быть объявлены как private, public, protected или static; не могут иметь внутри себя статических объявлений; исключением являются константы (static final); Анонимный класс (anonymous class) - это локальный класс без имени. Типичный пример - реализация Runnable: new Thread(new Runnable() { public void run() { ... } }).start(); Основное ограничение при использовании анонимных классов - это невозможность описания конструктора, так как класс не имеет имени. Внутренние классы-члены ассоциируются не с самим внешним классом, а с его экземпляром. При этом они имеют доступ ко всем его полям и методам. Например: public class OuterClass { public void method() { ... } public class InnerClass { public void method() { ... } public void anotherMethod() { method(); } } } InnerClass имеет доступ в членам класса OuterClass, как видно на примере метода anotherMethod, который вызывает метод method. Создать такой класс можно так: OuterClass outer = new OuterClass(); OuterClass.InnerClass innerClass = outer.new InnerClass();

Ответ 2



Внутренний (inner): Требует объект родительского класса для создания, жестко связан с ним. Объект имеет доступ к приватным полям родительского объекта Вложенный (nested): Не требует объект родительского класса для создания Не имеет доступа к приватным полям объектов родительского класса, но имеет доступ к приватным полям родительского класса. Код: public class Example { public static int si = 0; private static int psi = 0; public final Inner inner; public int i = 0; private int pi = 0; public Example() { inner = new Inner(); } public static class Nested { int e; public Nested() { e = Example.psi; e = Example.si; // а вот так нельзя // e = Example.this.pi; // e = Example.this.i; } } public class Inner { int e; public Inner() { e = Example.psi; e = Example.si; e = Example.this.pi; e = Example.this.i; } } } class ExampleTwo { // Nested можно сразу Example.Nested nested = new Example.Nested(); Example.Inner inner; { // так нельзя, нужен объект Example // inner = new Example.Inner(); // а так можно Example example = new Example(); inner = example.inner; } }

Комментариев нет:

Отправить комментарий