Java 8 лямбда-выражения-как насчет нескольких методов во вложенном классе



Я читаю о новых функциях по адресу: http://www.javaworld.com/article/2078836/java-se/love-and-hate-for-java-8.html



Я видел пример ниже:



Используя Анонимный Класс:



button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
System.out.println("Action Detected");
}
});


С Лямбда:



button.addActionListener(e -> {
System.out.println("Action Detected");
});


что бы кто-то сделать с MouseListener если они хотели реализовать несколько методов в анонимном классе, например:



public void mousePressed(MouseEvent e) {
saySomething("Mouse pressed; # of clicks: "
+ e.getClickCount(), e);
}

public void mouseReleased(MouseEvent e) {
saySomething("Mouse released; # of clicks: "
+ e.getClickCount(), e);
}


... и так далее?

544   5  

5 ответов:

С JLS 9.8

функциональный интерфейс-это интерфейс, который имеет только один абстрактный метод, и таким образом представляет один контракт функции.

лямбды требуют этих функциональных интерфейсов, поэтому ограничены их единственным методом. Анонимные интерфейсы по-прежнему необходимо использовать для реализации многомодовых интерфейсов.

addMouseListener(new MouseAdapter() {

    @Override
    public void mouseReleased(MouseEvent e) {
       ...
    }

    @Override
    public void mousePressed(MouseEvent e) {
      ...
    }
});

вы можете использовать многомодовые интерфейсы с лямбдами с помощью вспомогательных интерфейсов. Это работает с такими интерфейсами слушателя, где реализации нежелательных методов тривиальны (т. е. мы можем просто сделать то, что MouseAdapter тоже предлагает):

// note the absence of mouseClicked…
interface ClickedListener extends MouseListener
{
    @Override
    public default void mouseEntered(MouseEvent e) {}

    @Override
    public default void mouseExited(MouseEvent e) {}

    @Override
    public default void mousePressed(MouseEvent e) {}

    @Override
    public default void mouseReleased(MouseEvent e) {}
}

вам нужно определить такой вспомогательный интерфейс только один раз.

теперь вы можете добавить прослушиватель для события на Componentc такой:

c.addMouseListener((ClickedListener)(e)->System.out.println("Clicked !"));

лямбда, например, рассматривал этот вопрос. Многие библиотеки используют функциональные интерфейсы, хотя они были разработаны за несколько лет до того, как функциональный интерфейс стал вещью. Но иногда случается, что класс имеет несколько абстрактных методов, и вы хотите только нацелить один из них на лямбду.

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

static MouseListener clickHandler(Consumer<MouseEvent> c) { return ... }

Это может быть сделано непосредственно самими API (это могут быть статические методы внутри MouseListener) или могут быть внешними вспомогательными методами в какой-либо другой библиотеке, если сопровождающие предпочитают не предлагать это удобство. Поскольку набор ситуаций, в которых это было необходимо, невелик, а обходной путь настолько прост, он не казался убедительным для дальнейшего расширения языка, чтобы спасти этот угловой случай.

аналогичный трюк был использован для ThreadLocal; см. новый статический заводской метод withInitial(Supplier<S>).

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

A Java ActionListener необходимо реализовать только один метод (actionPerformed(ActionEvent e)). Это прекрасно вписывается в Java 8 функции Итак, Java 8 предоставляет простую лямбду для реализации ActionListener.

The MouseAdapter требуются по крайней мере два метода, поэтому не подходит в качестве function.

методы по умолчанию не могут быть доступны внутри лямбда-выражения. Следующий код не компилируется:

interface Formula {
    double calculate(int a);

    default double sqrt(int a) {
        return Math.sqrt(a);
    }
}
Formula formula = (a) -> sqrt( a * 100);

работает только с функциональным интерфейсом(только один абстрактный метод +любое количество методов по умолчанию), поэтому лямбда-выражение работает только с абстрактным методом

Comments

    Ничего не найдено.