You already have the name of the required mechanism - generics !
First create an event class:
abstract class AbstractEvent {
}
There is nothing strange about this. Then create a parameterized class / listener interface and give its type parameter the upper bound of your event object class:
interface Listener<T extends AbstractEvent> {
void process(T event);
}
:
class PonyEvent extends AbstractEvent {
}
, , , . :
class LoggingPonyListener implements Listener<PonyEvent> {
@Override
public void process(PonyEvent event){
System.out.println("Pony event occurred: " + event);
}
}
, :
class EventDispatcher<T extends AbstractEvent> {
private final List<Listener<T>> listeners =
new CopyOnWriteArrayList<Listener<T>>();
public void addListener(Listener<T> listener) {
listeners.add(listener);
}
public void dispatchEvent(T event) {
for (Listener<T> listener : listeners)
listener.process(event);
}
}
, ? :
EventDispatcher<PonyEvent> dispatcher = new EventDispatcher<PonyEvent>();
dispatcher.add(new LoggingPonyListener());
dispatcher.dispatchEvent(new PonyEvent());
, , , , . . , , , , , .
EventDispatcher, :
class DebugListener implements Listener<AbstractEvent> {
private final String msg;
public DebugListener(String msg) { this.msg = msg; }
@Override
public void process(AbstractEvent event){
System.out.println(msg);
}
}
, ? . :
EventDispatcher<PonyEvent> dispatcher = new EventDispatcher<PonyEvent>();
dispatcher.add(new DebugListener("pony event"));
DebugListener Listener<AbstractEvent>, a Listener<PonyEvent>. :
class EventDispatcher<T extends AbstractEvent> {
private final List<Listener<? super T>> listeners =
new CopyOnWriteArrayList<Listener<? super T>>();
public void addListener(Listener<? super T> listener) {
listeners.add(listener);
}
public void dispatchEvent(T event) {
for (Listener<? super T> listener : listeners)
listener.process(event);
}
}
: , PonyEvent process Listener<AbstractEvent> ( a PonyEvent is-an AbstractEvent), , , , .