2016-01-29 2 views
1

Я создаю обработку рамки событие, и хотел бы сделать следующее:Вызов нестатического ссылка метода объекта с аргументом

// E: event listener interface, T: event class 
class EventManager<E, T> { 

    ArrayList<E> listeners = new ArrayList<E>(); 

    // `method` is some sort of reference to the method to call on each listener. There is no `MethodReference` type, I just put it there as I'm not sure what type should be in its place 
    protected void notifyListeners(MethodReference method, T eventObj) { 
     for (E listener : listeners) // call `method` from `listener` with `eventObj` as an argument 
    } 
} 

class SpecialisedEventManager extends EventManager<SomeListener, SomeEvent> { 

    // Some method that would want to notify the listeners 
    public void foo() { 
     ... 
     // I would like onEvent() to be called from each listener with new SomeEvent() as the argument 
     notifyListeners(SomeListener::onEvent, new SomeEvent()); 
     ... 
    } 

    // Some other method that would want to notify the listeners 
    public void bar() { 
     ... 
     notifyListeners(SomeListener::onOtherEvent, new SomeEvent()); 
     ... 
    } 

} 

interface SomeListener { 
    public void onEvent(SomeEvent event); 
    public void onOtherEvent(SomeEvent event); 
} 

Но я не уверен, как ссылаться на onEvent() и onOtherEvent(), чтобы они вызывались из каждого объекта-слушателя с соответствующим аргументом. Есть идеи?

+0

Как выглядит интерфейс 'MethodReference'? – Flown

+0

@Flown Это на самом деле не существует, я просто положил его туда, чтобы он соответствовал синтаксису Java. Я не уверен, какой тип должен быть на его месте. – SamTebbs33

+3

И почему вы не нашли [поиск] (http://docs.oracle.com/javase/8/docs/api/?java/util/function/package-summary.html) для соответствующего интерфейса? Все, что вам нужно сделать, это поиск параметров и возвращаемого типа ... – Holger

ответ

3

Ссылка на метод - это всего лишь способ реализовать функциональный интерфейс, поэтому вам нужно либо определить собственный интерфейс, либо search the predefined types для соответствия.

Поскольку ваш метод слушателя потребляет экземпляр целевого слушателя и объект события и не возвращает значение, BiConsumer является соответствующим типом:

protected void notifyListeners(BiConsumer<E,T> method, T eventObj) { 
    for(E listener: listeners) 
     method.accept(listener, eventObj); 
} 

Метод ссылается SomeListener::onEvent и SomeListener::onOtherEvent имеет вид “Reference to an instance method of an arbitrary object” где вызывающий обеспечивает целевой экземпляр для вызова метода on, аналогично лямбда-выражениям (l,e) -> l.onEvent(e) и (l,e) -> l.onOtherEvent(e), поэтому целевой экземпляр становится первым функциональным параметром.

+0

Отлично, спасибо! – SamTebbs33

Смежные вопросы