JavaRush /Java блог /Random UA /Кава-брейк #182. Функціональні інтерфейси в Java

Кава-брейк #182. Функціональні інтерфейси в Java

Стаття з групи Random UA
Джерело: DZone Вашій увазі представлений огляд функціональних інтерфейсів у Java: призначення, приклади, лямбда-вирази та список встановлених інтерфейсів. Кава-брейк #182.  Функціональні інтерфейси в Java - 1Будучи об'єктно-орієнтованою мовою програмування, Java раніше не могла мати незалежні функції, оскільки в цій мові все, окрім деяких примітивних типів даних та методів, обертається навколо класів та об'єктів. Однак у Java 8 з'явилася нова концепція, яка називається функціональним інтерфейсом, а також деякі інші фічі, такі як Lambda Expressions, Time API, Stream API і таке інше. Що це за функціональні інтерфейси і як їх визначити? Давай з'ясуємо!

Що таке інтерфейс?

Інтерфейс – це сукупність правил, що визначають взаємодію елементів системи. Він також відомий як схема класу, що містить абстрактні методи та статичні константи. Інтерфейс може містити один або кілька абстрактних методів. Також інтерфейси дозволяють ставити вимоги до класів, тобто які методи вимагаються від класу. Простіше кажучи, інтерфейс подібний до контракту, який повинен дотримуватися кожним реалізуючим класом. Ось приклад:
Interface A1
{
void method1();
String method2(String X);
}

Class A1 implements A
{
@Override
public void method1(){}
@Override
public String method2(String X) { return x; }
}
Якщо клас, що реалізує інтерфейс, не оголошує всі методи інтерфейсу, код не запуститься і видасть помилку: “ error: A1 не є abstract і не може бути зайвим, а abstract метод в A1. (помилка: A1 не є абстрактним і не перевизначає абстрактний метод в A1). До JDK 8 інтерфейси не могли визначати реалізації, але тепер для інтерфейсних методів можна додати реалізації за замовчуванням. Ми також можемо визначити статичні методи та методи за замовчуванням, які можна викликати без об'єкта в інтерфейсі.В основному інтерфейси використовуються для досягнення множинного успадкування та слабкого зв'язку в коді.Тепер, коли у нас є чітке уявлення про інтерфейси, давайте подивимося, що таке функціональний інтерфейс і як він працює.

Що таке багатофункціональний інтерфейс?

Функціональний інтерфейс також відомий як інтерфейс єдиного абстрактного методу (Single Abstract Method, SAM). Як випливає із назви, він може мати не більше одного абстрактного методу. Функціональний інтерфейс може мати кілька статичних методів та методів за промовчанням з реалізацією, а також додатковий абстрактний метод. Щоб позначити інтерфейс як функціональний, використовується інструкція @FunctionalInterface . Вона потрібна, щоб уникнути помилкового оголошення додаткових методів. Що робить функціональний інтерфейс таким популярним, то це можливість використання лямбда-виразів для створення інтерфейсів без використання анонімних та громіздких реалізацій класів. Використання ключового слова abstract у функціональних інтерфейсах не є обов'язковим, оскільки методи, визначені всередині інтерфейсу, за умовчанням є абстрактними.

Що таке лямбда-вирази?

Лямбда-вираз — це безіменний чи анонімний метод, який виконується сам собою, а використовується реалізації певних методів функціонального інтерфейсу. Він визначається так:
(parameter list) -> lambda body
Оператор стрілки ( -> ), який ви бачите у коді, відомий як лямбда-оператор. Наприклад, якщо ми маємо наступний метод:
double getGoldenRatioValue() {
return 1.61803;
}
Використовуючи лямбда-вираз, ми можемо його записати так:
() -> 1.61803
Як бачите, метод у лямбда-функції не має параметрів, тому ліва частина оператора порожня. Оскільки права сторона визначає дію, то цьому прикладі вона поверне значення золотого перерізу: 1,61803. До появи Java 8 реалізація інтерфейсів чи створення об'єктів внутрішнього класу мали вирішальне значення, але з появою Java 8 все, що нам тепер потрібно робити, це призначати лямбда-вираження функціональним інтерфейсам.

Приклади функціональних інтерфейсів

Для створення функціональних інтерфейсів ви можете використовувати анотацію @FunctionalInterface , або використовувати певні функціональні інтерфейси Java.

Приклад 1

  • Спочатку ми створимо позначку @FunctionalInterface і створимо інтерфейс, під ім'ям MyInterface , який викликається абстрактним методом getGoldenRationValue() .
  • Потім ми створимо громадський клас main виконання методу.
  • Щоб використовувати лямбда-вираз у функціональному інтерфейсі, ми оголосимо посилання на MyInterfaceDemo , а потім призначимо лямбда-вираз цього посилання.
  • Нарешті, ми надрукуємо значення золотого перерізу, використовуючи reference interface.
import java.lang.FunctionalInterface;

// створення и маркировка функционального интерфейса
@FunctionalInterface

interface MyInterface {
// Это абстрактный метод
double getGoldenRatioValue();
}

public class Main {
public static void main( String[] args ) {

//декларируем ссылку на функциональный интерфейс
MyInterface ref;
//используем Lambda Expression
ref = () -> 1.61803;

System.out.println("Value of Golden Ratio = " + ref.getGoldenRatioValue());
}
}
Висновок:
Value of Golden Ratio = 1.61803

Приклад 2

  • У цьому прикладі ми збираємося використовувати зумовлений функціональний інтерфейс ToDoubleFunction , який приймає аргумент T і повертає значення типу double як висновок.
  • ToDoubleFuntion містить абстрактний метод з ім'ям applyasDouble() .
  • І, нарешті, ми друкуємо повідомлення по всій довжині, включаючи прогалини.
import java.util.function.ToDoubleFunction;
public class MyInterface2 {

public static void main(String[] args) {

ToDoubleFunction<String> length = x -> x.length();

System.out.println(length.applyAsDouble("This is an example of predefined functional interface."));
}
}
Висновок:
54.0

Список встановлених функціональних інтерфейсів

Тепер, коли ми знаємо, як визначати функціональні інтерфейси, погляньмо, скільки існує зумовлених (вбудованих) функціональних інтерфейсів. Є 4 основних типи функціональних інтерфейсів, які можна реалізувати в різних ситуаціях: Consumer , Predicate , Function та Supplier . Серед цих чотирьох інтерфейсів Consumer , Function та Predicate мають додаткові функціональні інтерфейси. Ось список всіх вбудованих або зумовлених інтерфейсів Java. Примітка. T, U і R, згадані в таблиці нижче, є типом першого аргументу (T), другого аргументу (U) і результату (R) операції відповідно.
Interface Type
Runnable
BiConsumer(T, U) T, U →
BiFunction(T, U, R) T, U → R
BinaryOperator T, T <→ R
BiPredicate<T, U> T, U → boolean
BooleanSupplier → boolean
Consumer T →
DoubleBinaryOperator double, double → double
DoubleConsumer double →
DoubleFunction double → R
DoublePredicate double → boolean
DoubleSupplier boolean →
DoubleToIntFunction double → int
DoubleToLongFunction double → long
DoubleUnaryOperator double → double
Function<T, R> T → R
IntBinaryOperator int → int
IntConsumer int →
IntFunction int → R
IntPredicate int → boolean
IntSupplier → int
IntToDoubleFunction int → double
IntToLongFunction int → long
IntUnaryOperator int → int
LongBinaryOperator long, long → long
LongConsumer long →
LongFunction long → R
LongPredicate long →
LongSupplier → long
LongToDoubleFunction long → double
LongToIntFunction long → int
LongUnaryOperator long → long
ObjDoubleConsumer T, double →
ObjIntConsumer T, int →
ObjLongConsumer T, long →
Predicate T → boolean
Supplier → T
ToDoubleBiFunction<T, U> T, U → double
ToDoubleFunction T → double
ToIntBiFunction<T, U> T, U → int
ToIntFunction T → int
ToLongBiFunction<T, U> T, U → long
ToLongFunction T → long
UnaryOperator T → T

Підбиваємо підсумки

Деякі ключові висновки, які слід запам'ятати з цієї публікації:
  • Інтерфейс працює як механізм абстракції.
  • Функціональний інтерфейс може мати кілька статичних методів та методів за промовчанням з реалізацією, а також додатковий абстрактний метод.
  • Методи, визначені всередині функціонального інтерфейсу, за умовчанням є абстрактними, тому використання ключового слова abstract тепер необов'язкове.
  • Лямбда-вираз — це анонімний метод, який виконується сам собою, а використовується реалізації певних методів функціонального інтерфейсу.
  • Для створення функціональних інтерфейсів ви можете використовувати анотацію @FunctionalInterface , або використовувати певні функціональні інтерфейси Java.
Коментарі
ЩОБ ПОДИВИТИСЯ ВСІ КОМЕНТАРІ АБО ЗАЛИШИТИ КОМЕНТАР,
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ