Лекция 7
Тема: Анонимные классы, интерфейсы, методы. Лямбда-выражения. Встроенные функциональные интерфейсы. Ссылка на методы и конструкторы.
При создании объектов с помощью оператора new возвращается ссылка на вновь созданный объект. Однако нас никто не обязывает эту ссылку присваивать в качестве значения ссылочной переменной. В таких случаях создается анонимный объект. Другими словами, объект есть, а переменной, которая бы содержала ссылку на этот объект, нет.
С практической точки зрения это может выглядеть бесполезным, однако, анонимные объекты требуются довольно часто - обычно в тех ситуациях, когда объект класса используется один раз. Рассмотрим пример:
class PrintManager {
// Различные поля и методы
public void printFile(File file) {
// Распечатка файла на принтере
}
}В данном случае, нам нужен объект класса PrintManager только для одного действия - для распечатки файла. То есть, мы создаем объект, вызываем метод, после чего объект нам больше не нужен.
В таких случаях удобно использовать анонимные объекты.
File file = new File("file.txt");
// Обычное создание объекта и вызов его метода
PrintManager manager = new PrintManager();
manager.printFile(file);
// Использование анонимного объекта
new PrintManager().printFile(file);
// Использование двух анонимных объектов
new PrintManager().printFile(new File("file.txt"));В первом случае используется обычный порядок работы с объектами - создаем объект класса PrintManager, ссылка на объект записывается в ссылочную переменную manager.
Во втором случае мы создаем анонимный объект. Инструкция
выполняется следующим образом. Сначала создается новый объект класса PrintManager, оператор new возвращает ссылку на созданный объект. После чего, мы вызываем метод printFile() с аргументом file.
В третьем случае, мы в качестве аргумента метода printFile() передаем анонимный объект класса File. В этом случае, ссылку на объект класса File будет хранить параметр метода printFile() внутри тела метода.
Анонимные классы
Механизм анонимных классов позволяет объявить класс и сразу создать его экземпляр. Это позволяет сделать код кратким и выразительным. Анонимные классы удобно использовать, если класс нужен единожды.
Основная особенность - анонимный класс не имеет имени. Анонимный класс может быть подклассом существующего класса или реализацией интерфейса.
Особенности анонимного класса:
нет явного конструктора;
к анонимному классу невозможно обратиться извне объявляющего его выражения;
анонимные классы не могут быть статическими;
анонимный класс всегда конечен (
final);каждое объявление анонимного класса уникально.
В примере ниже объявлены два анонимный класса, которые являются подклассами PrintManager. Оба анонимных класса являются разными уникальными классами.
Анонимные методы (лямбда-выражения)
Из-за особенностей реализации лямбда-выражений в Java, дальнейшая информация по поводу лямбда-выражений справедлива только для языка Java.
Лямбда-выражение - это анонимный метод, то есть метод без названия. Такой метод выполняется не самостоятельно, а служит для реализации функционального интерфейса. Таким образом, лямбда-выражение приводит к некоторой форме анонимного класса.
Функциональный интерфейс - интерфейс, который содержит один и только один абстрактный метод. Как правило, такой метод определяет предполагаемое назначение интерфейса. Следовательно, функциональный интерфейс представляет единственное действие. К функциональным интерфейсам можно отнести, например, интерфейс ActionListener.
Лямбда-выражения позволяют объявить метод и сразу же использовать его. Это полезно в случаях однократного вызова метода, так как сокращает время на объявление и написание метода без необходимости создавать отдельный класс. Лямбда-выражение в Java имеет следующий синтаксис:
Лямбда-выражение вносит новый элемент в синтаксис и оператор в язык Java. Этот новый оператор называется лямбда-оператором, или операцией "стрелка" ->. Он разделяет лямбда-выражение на две части. В левой части указываются любые параметры, требующиеся в лямбда-выражении (если параметры не требуются, то они указываются пустым списком). А в правой части находится тело лямбда-выражения, где указываются действия, выполняемые лямбда-выражением. Операция -> буквально означает "становиться" или "переходить".
В Java определены две разновидности тел лямбда-выражений. Одна из них состоит из единственного выражения (одиночное выражение), а другая - из блока кода (блочное выражение).
Одиночное лямбда-выражение.
Для начала рассмотрим самое простое лямбда-выражение. Это будет выражение, которое не принимает никаких параметров, а возвращает константу. Также объявим метод, который аналогичен лямбда-выражению.
Приведем еще один пример уже более полезного выражения
Как вам понятно, лямбда-выражение возвращает псевдослучайное значение, умноженное на 100.
Два первых примера не принимают никаких параметров. Если же вам необходимо передать параметры, они указываются списком в левой части лямбда-оператора.
Тип параметров можно указывать явно, но зачастую в этом нет необходимости, потому что тип параметров выводится.
Блочные лямбда-выражения
Предыдущие примеры содержали в теле выражения лишь одно выражение. Мы уже знаем, что такие лямбда-выражения называются одиночными.
Но ничего вам не мешает создавать блочные лямбда-выражения, которые в теле содержат блок выражений. В таком блоке можно создавать циклы, ветвления - все как в обычном блоке выражений.
При создании блочного выражения необходимо явно указать оператор return.
Функциональные интерфейсы. Ссылки на методы и конструкторы.
Лямбда-выражение как реализация интерфейса
Как было упомянуто ранее, в Java 8 было введено понятие функционального интерфейса - интерфейса с одним абстрактным методом. Лямбда-выражение не существует самостоятельно, а реализует абстрактный метод, определенный в функциональном интерфейсе.
Таким образом, лямбда может быть указана в том контексте, в котором определен ее целевой тип. Один из таких контекстов создается в том случае, когда лямбда присваивается ссылке на функциональный интерфейс. К числу других контекстов целевого типа относится инициализация переменных, оператор return и аргументы методов.
Данная тема находится в процессе оформления материала.
Last updated
Was this helpful?