Transcript
Page 1: Вложенные классы и интерфейсы

Вложенные классы и интерфейсы.

Виталий Унгурян [email protected]

Page 2: Вложенные классы и интерфейсы

Вложенный класс

Вложенный класс - это класс, который объявлен

внутри тела другого класса. 

Page 3: Вложенные классы и интерфейсы

Вложенные классы

Вложенные классы делятся на два вида: статические не статические.

Page 4: Вложенные классы и интерфейсы

Вложенные классы

Вложенные классы, объявленные как статические называются вложенными статическими (static nested classes). Не статические называются внутренними (inner classes).

Page 5: Вложенные классы и интерфейсы

Вложенные классы (nested)

class OuterClass {    ...    static class NestedClass {        ...    }}

Page 6: Вложенные классы и интерфейсы

Вложенные классы (inner)

class OuterClass {    ...    class NestedClass {        ...    }}

Page 7: Вложенные классы и интерфейсы

Доступ к переменным

Статические — не имеют доступ к членам обрамляющего класса. Как и другие поля класса, вложенные классы могут быть объявлены как private, public, protected или package private.

Page 8: Вложенные классы и интерфейсы

Доступ к переменным

Не статические классы имеют доступ к полям

обрамляющего класса, даже если они объявлены как

private.

Page 9: Вложенные классы и интерфейсы

Использование вложенных классов

Это хороший способ группировки классов, которые используются только в одном месте:

Если класс полезен (используется) только внутри одного класса, то логично будет держать их вместе. Вложение таких вспомогательных классов делает код более удобным.

Page 10: Вложенные классы и интерфейсы

Использование вложенных классов

Инкапсуляция: Допустим, есть два класса A и B,

классу B требуется доступ к свойству класса A, которое может быть приватным. Вложение класса B в класс A решит эту проблему, более того сам класс B можно скрыть от внешнего использования.

Page 11: Вложенные классы и интерфейсы

Использование вложенных классов

Улучшение читаемости и обслуживаемости кода:

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

Page 12: Вложенные классы и интерфейсы

Доступ к вложенным классам

Доступ к вложенному классу осуществляется с помощью следующей конструкции:OuterClass.StaticNestedClassСинтаксис создания объекта вложенного класса:OuterClass.StaticNestedClass nestedObject =  new OuterClass.StaticNestedClass();

Page 13: Вложенные классы и интерфейсы

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

Внутренние (не статические) классы, как переменные и методы связаны с объектом внешнего класса.

Внутренние классы так же имеют прямой доступ к полям внешнего класса.

Page 14: Вложенные классы и интерфейсы

Ограничения внутрених классов

Внутренние классы не могут содержать в себе статические методы и поля.

Внутри внутренних классов нельзя объявлять перечисления.

Page 15: Вложенные классы и интерфейсы

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

Внутренние классы не могут существовать без экземпляра внешнего.

Page 16: Вложенные классы и интерфейсы

Создание объекта внутреннего класса

Outer outerObject = new Outer();Outer.Inner innerObject = outerObject.new Inner();

Page 17: Вложенные классы и интерфейсы

Пример внутренних классов

public class OuterClass {     public void method() { ... }      public class InnerClass {         public void method() { ... }                  public void anotherMethod() {             method();         }     } } 

Page 18: Вложенные классы и интерфейсы

Затенение (shadowing)

Если вы объявляете переменную (будь то параметр или свойство класса) в какой-либо области (например, вложенный класс или область метода) с именем уже занятым в данной области, то такое объявление «затеняет» предыдущее и вы не сможете обращаться напрямую к переменной по её имени.

Page 19: Вложенные классы и интерфейсы

Пример затенения

public class ShadowTest {    public int x = 0;    class FirstLevel {        public int x = 1;        void methodInFirstLevel(int x) {            System.out.println("x = " + x);            System.out.println("this.x = " + this.x);            System.out.println("ShadowTest.this.x = " + ShadowTest.this.x);        }    }   

Page 20: Вложенные классы и интерфейсы

Пример затенения

    public static void main(String... args) {        ShadowTest st = new ShadowTest();        ShadowTest.FirstLevel fl = st.new FirstLevel();        fl.methodInFirstLevel(23);    }}

Page 21: Вложенные классы и интерфейсы

Локальные классы

Локальные классы похожи на внутренние: они не могут содержать статические поля или методы.

Page 22: Вложенные классы и интерфейсы

Ограничения локальных классов

У локальных классов есть множество ограничений:Они видны только в пределах блока, в котором объявлены;Вы не сможете объявить интерфейс внутри метода — интерфейсы статичны.

Page 23: Вложенные классы и интерфейсы

Ограничения локальных классов

Локальный класс может содержать статические поля, только если они константы.

Они не могут быть объявлены как private, public, protected или static;

Page 24: Вложенные классы и интерфейсы

Локальные классы

На практике чаще всего объявление происходит в методе некоторого другого класса.

Хотя объявлять локальный класс можно внутри статических и нестатических блоков инициализации.

Page 25: Вложенные классы и интерфейсы

Анонимные классы

Анонимные классы, в отличие от локальных, не имеют имени. В отличие от объявления обычных классов, объявление анонимных классов происходит внутри выражения. Используйте анонимные классы, если локальный класс нужен вам единожды.Анонимные классы часто используются в приложениях с графическим интерфейсом (GUI).

Page 26: Вложенные классы и интерфейсы

Пример анонимного класса

new Thread(new Runnable() { public void run() { ... } }).start();

Page 27: Вложенные классы и интерфейсы

Синтаксис анонимного класса

Определение анонимного класса содержит:Оператор newИмя интерфейса для реализации или класса для наследования. Скобки, также как и при создании обычных объектов. Можно реализовать интерфейс или абстрактный класс.

Page 28: Вложенные классы и интерфейсы

Доступ к локальным переменным

Анонимный класс имеет доступ к полям внешнего класса.

Анонимный класс не имеет доступ локальным переменным области, в которой он определен, если они не финальные (final) или неизменяемые (effectively final).

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

Page 29: Вложенные классы и интерфейсы

Ограничения анонимных классов

Нельзя определять статические члены анонимного класса.

Анонимный класс может содержать статические поля, если это константы.

Анонимные классы также могут содержать в себе локальные классы. Конструктора в анонимном классе быть не может.

Page 30: Вложенные классы и интерфейсы

Использование final для классов

Класс с final не может подразделяться на подклассы. От такого класса нельзя наследоваться. Если класс объявлен final и abstract (взаимоисключающие понятия), произойдет ошибка компиляции 

Page 31: Вложенные классы и интерфейсы

Использование final для методов

Метод с final не может быть переопределен в наследнике.Аргументы методов, обозначенные как final, предназначены только для чтения, при попытке изменения будет ошибка компиляции.

Page 32: Вложенные классы и интерфейсы

Использование final для переменных

Переменные final не инициализируются по умолчанию, им необходимо явно присвоить значение при объявлении или в конструкторе, иначе – ошибка компиляции.Если final переменная содержит ссылку на объект, объект может быть изменен, но переменная всегда будет ссылаться на тот же самый объект 

Page 33: Вложенные классы и интерфейсы

Вложенные интерфейсы

Интерфейс может быть объявлен членом класса или другого интерфейса. Такой интерфейс называется интерфейсом-членом или вложенным интерфейсом. Вложенный интерфейс может быть объявлен как public, private или protected.

Page 34: Вложенные классы и интерфейсы

Пример вложенного интерфейса

class A { interface B { void f(); } public class C implements B { public void f() {} } private class D implements B { public void f() {} }}

Page 35: Вложенные классы и интерфейсы

Вложенные в интерфейсы классы.

Вложенный (nested) в интерфейс класс является открытым (public) и статическим (static) даже без явного указания этих модификаторов. Помещая класс внутрь интерфейса, мы показываем, что он является неотъемлемой частью API этого интерфейса и более нигде не используется.

Page 36: Вложенные классы и интерфейсы

interface Colorable { public Color getColor(); public static class Color { private int red, green, blue; Color(int red, int green, int blue) { this.red = red; this.green = green; this.blue = blue; }

Page 37: Вложенные классы и интерфейсы

int getRed() { return red; } int getGreen() { return green; } int getBlue() { return blue; } } } class Triangle implements Colorable { private Color color; // ... @Override public Color getColor() { return color; } }

Page 38: Вложенные классы и интерфейсы

Использование

Colorable.Color color = new Colorable.Color(0, 0, 0); color = new Triangle.Color(255, 255, 255);

Page 39: Вложенные классы и интерфейсы

Recommended