Добавил:
Rumpelstilzchen2018@yandex.ru Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

3-й семестр / Лекции / 4 - Презентация 2 - ООП

.pdf
Скачиваний:
65
Добавлен:
25.12.2020
Размер:
596.48 Кб
Скачать

Центр дистанционного обучения

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

Таким образом, невозможно создать отдельно стоящий объект не-статического вложенного класса Point – он может быть создан только имея ссылку на объект Shape. При создании объекта Point внутри класса Shape компилятор неявно заполняет поле this$0 ссылкой this:

class Shape {

...

Point p = new Point(1, 2);

// Компилятор заменяет на new Point(this, 1, 2)

online.mirea.ru

Центр дистанционного обучения

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

Для создания объектов не-статических вложенных классов извне класса Shape используется синтаксис:

Shape s1 = ...;

Shape.Point p1 = s1.new Point(1, 2);

// При этом p1.this$0 заполняется ссылкой на s1

online.mirea.ru

Центр дистанционного обучения

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

Внутри не-статического вложенного класса можно ссылаться на поля и методы объемлющего класса. При этом эти методы вызываются у объекта this$0.

public class Shape {

public class Point {

public void test() {

System.out.println(getArea()); // Вызов this$0.getArea()

}

}

public double getArea() { return 0; }

}

online.mirea.ru

Центр дистанционного обучения

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

public interface HasArea { double getArea();

}

Анонимные классы – всегда либо наследуются от базового класса, либо реализуют интерфейс.

online.mirea.ru

Центр дистанционного обучения

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

HasArea squareMeter = new HasArea() { @Override

public double getArea() { return 1; }

};

Объект squareMeter принадлежит безымянному классу, реализующему интерфейс HasArea с реализацией метода getArea, возвращающей 1.

online.mirea.ru

Центр дистанционного обучения

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

Анонимные классы могут захватывать переменные, доступные в области видимости:

public static void main(String[] args) { double side = 2;

HasArea square = new HasArea() { @Override

public double getArea() { return side * side; }

};

}

online.mirea.ru

Центр дистанционного обучения

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

Захватываемые переменные должны быть effective final, т.е. быть присвоены только один раз. Если бы было разрешено менять переменные, то:

double side = 2;

HasArea square = new HasArea() {

@Override double getArea() { return side * side; }

};

side = 3; // Что теперь возвращает square.getArea()?

// Либо 4, либо 9. Для устранения неоднозначности

// менять захватываемые переменные запрещено

online.mirea.ru

Центр дистанционного обучения

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

public class Example {

private double getSide() { return 2;

}

public void test() {

HasArea square = new HasArea() { @Override

public double getArea() {

//Анонимный класс может ссылаться на

//методы и поля объемлющего класса return getSide() * getSide();

}

}; System.out.println(square.getArea());

}

}

online.mirea.ru

 

Центр дистанционного обучения

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

public class Example {

private double getSide() { return 2;

}

public void test() {

HasArea rectangle = new HasArea() { public double getSide() {

return 3;

}

@Override

public double getArea() {

return this.getSide() * // обращение к методу анонимного класса Example.this.getSide(); // обращение к методу объемлющего класса

}

};

}

}

online.mirea.ru

Центр дистанционного обучения

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

Если анонимный класс реализует интерфейс с одим методом, то его запись может быть сокращена:

HasArea square1 = new HasArea() {

@Override public double getArea() { return 1; }

}

HasArea square2 = () -> { return 1; }

HasArea square3 = () -> 1;

Это так называемые лямбда-выражения.

online.mirea.ru