Я не уверен, почему интерфейсы не настолько универсальны для вас - вы можете делать с интерфейсами все что угодно, конечно, столько же, сколько вы можете делать с передачей чистых функций.
Обычно вы просто определяетеинтерфейс одного обработчика событий:
public interface EventHandler {
public ReturnType handle(ParamType param);
}
Тогда вы можете реализовать этот интерфейс с любым количеством различных классов обработчиков.Объекты-обработчики могут даже содержать свое собственное состояние, если это полезно.
Все, что вы определяете для реализации интерфейса, может затем использоваться полиморфно, например, храниться в массиве, чтобы их можно было вызывать в ответ на конкретное событие.