прошу сильно не тролити, тільки починаю перекладати статті
Інтерфейс може успадковуватися від іншого інтерфейсу, якщо інтерфейс успадковується від функціонального інтерфейсу і не містить нових абстрактних методів, тоді цей інтерфейс також є функціональним. Але інтерфейс може містити лише один абстрактний метод і безліч дефолтних методів, і він досі вважатиметься функціональним.
Введення у функціональні інтерфейси – концепції відтворені у Java 8
Будь-який розробник Java у світі хоча б раз використовував один із таких інтерфейсів:java.lang.Runnable
, java.awt.event.ActionListener
, java.util.Comparator
, java.util.concurrent.Callable
. Їх все поєднує одна спільна риса, і це те, що у всіх них є тільки один метод. Існує безліч інших таких інтерфейсів у JDK, а також інші створені розробниками Java. Ці інтерфейси також відомі як Single Abstract Method interfaces
(SAM interfaces). Одним із найпопулярніших способів використання цих інтерфейсів полягає у створенні анонімних внутрішніх класів, які використовують ці інтерфейси, як у наступному прикладі:
public class AnonymousInnerClassTest {
public static void main(String[] args) {
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("A thread created and running...");
}
}).start();
}
}
Java 8 концепція SAM відтворена і називається функціональними інтерфейсами. Вони можуть бути представлені за допомогою лямбда-виразів, посиланнями на методи та конструкторами посилань. Створено нову інструкцію @FunctionalInterface яка використовується для видачі помилок на рівні компілятора, коли інтерфейс який Ви анотували не працює на функціональному рівні. Давайте подивимося на простий функціональний інтерфейс з одним абстрактним методом:
@FunctionalInterface
public interface SimpleFunInterface {
public void doWork();
}
Інтерфейс також може оголошувати абстрактні методи з класу java.lang.Object
, але і в цьому випадку інтерфейс може оголошуватися функціональним:
@FunctionalInterface
public interface SimpleFuncInterface {
public void doWork();
public String toString();
public Boolean equals(Object o);
}
Як тільки Ви додали ще один абстрактний метод до інтерфейсу IDE помітить його помилковим як на картинці:
Що ще почитати: |
---|
@FunctionalInterface
public interface ComplexFunctionalInterface extends SimpleFuncInterface {
default public void doSomeWork() {
System.out.println("Doing some work in interface impl...");
}
default public void doSomeWork() {
System.out.println("Doing some other work in interface impl...");
}
}
Верхній приклад є функціональним інтерфейсом. Тепер розглянемо, як ми можемо використовувати лямбда-вирази для заміни анонімного внутрішнього класу для реалізації функціональних інтерфейсів:
/*
*Implementation the interface by creating an
*anonymoous inner class versus using
*lambda expression.
*/
public class SimpleFunInterfaceTest {
public static void main(String[] args) {
carryOutWork(new SimpleFunInterface() {
@Override
public void doWork() {
System.out.println("Do work in SimpleFun impl...");
}
});
carryOutWork(() -> System.out.println("Do work in lambda exp impl..."));
}
public static void carryOutWork(SimpleFuncInterface sfi) {
sfi.work();
}
}
Результат програми буде наступним:
Do work in SimpleFun impl...
Do work in lambda exp impl...
Якщо ви використовуєте IDE, яка підтримує синтаксис Java лямбда-виразів (Netbeans 8 Nightly builds) – Ви отримуєте підказку, коли використовуєте анонімні внутрішні класи: Це було коротке введення в концепцію функціональних інтерфейсів у Java 8, а також як вони можуть бути реалізовані за допомогою лямбда-виразів.
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ