Как данный код может выполняться и компилироваться если при action.perform, метод perform даже не определен. И плюс команда типа editor в момент m.record(editor::save);,
а сам список macro преназначен для объектов типа action? Как такое может быть?
public class Macro {
List
Macro(){
macro = new ArrayList<>();
}
public void record(Actiona action){
macro.add(action);
}
public void run(){
macro.forEach(Actiona::perform);
}
public static void main(String[] args) {
MockEditor editor = new MockEditor();
Macro m = new Macro();
m.record(editor::save);
m.record(editor::close);
m.run();
}
}
public class MockEditor implements Editor {
@Override
public void save() {
System.out.println("Save");
}
@Override
public void close() {
System.out.println("close");
}
}
public interface Actiona {
public void perform();
}
public interface Editor {
public void save();
public void close();
}
Ответ
Эту магию легко понять, если пойти в IDE (скажем IDEA) и попросить заменить лямду на анонимный класс:
public static void main(String[] args) {
MockEditor editor = new MockEditor();
Macro m = new Macro();
m.record(new Actiona() { // вместо m.record(editor::save);
@Override
public void perform() {
editor.save();
}
});
m.record(new Actiona() { // вместо m.record(editor::close);
@Override
public void perform() {
editor.close();
}
});
m.run(); // Вызываем метод с двумя объектами Actiona
И неожиданно все становится простым и понятным, мы реализуем метод perform вызывая внутри методы editor.save() и editor.close(), так что поведение вполне корректное.
Очень хорошое умение, как только запутался в ламбда-функциях, заменяй их мысленно (или с помощью IDE) на анонимные классы и жить становится проще.
Комментариев нет:
Отправить комментарий