Полиморфные вызовы функций в Java? - PullRequest
1 голос
/ 05 марта 2012

Можно ли полиморфно передать функцию в массив объектов в Java?

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

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

Ответы [ 4 ]

3 голосов
/ 05 марта 2012

Я бы хотел передать любую функцию менеджеру событий

Не все ли мы? К сожалению, в Java нет функций первого класса или даже указателей на функции. Таким образом, мы застряли с интерфейсами и анонимными классами, по крайней мере, до Java 8.

1 голос
/ 05 марта 2012

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

Обычно вы просто определяетеинтерфейс одного обработчика событий:

public interface EventHandler {
  public ReturnType handle(ParamType param);
}

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

Все, что вы определяете для реализации интерфейса, может затем использоваться полиморфно, например, храниться в массиве, чтобы их можно было вызывать в ответ на конкретное событие.

1 голос
/ 05 марта 2012

Почему бы вашему менеджеру событий не выполнить Runnable с и не обернуть вызов метода одним?(Это подход, который использовал Swing.)

public class Foo {
    public void doSomething(){
        System.out.println("Hello");
    }
}

EventQueue.doLater(new Runnable(){
    public void run(){
        new Foo().doSomething();
    }
}
0 голосов
/ 05 марта 2012

Java не поддерживает первоклассные функции. Но вы можете сделать это почти с помощью анонимных классов или класса EventHandler.

Это из Java Docs.

Самое простое использование EventHandler - установить прослушиватель, который вызывает метод для целевого объекта без аргументов. В следующем примере мы создаем ActionListener, который вызывает метод toFront для экземпляра javax.swing.JFrame.

myButton.addActionListener(
    (ActionListener)EventHandler.create(ActionListener.class, frame, "toFront"));

Когда нажимается myButton, выполняется оператор frame.toFront (). Этого же эффекта можно добиться с некоторой дополнительной безопасностью типов во время компиляции, определив новую реализацию интерфейса ActionListener и добавив ее экземпляр к кнопке:

//Equivalent code using an inner class instead of EventHandler.
myButton.addActionListener(new ActionListener() {
    public void actionPerformed(ActionEvent e) {
        frame.toFront();
    }
});
...