ок. тогда зачем нужен интерфейс если диспатчер так хорош? что ни коля ни вася не испортят логику?
потому что это разные вещи для разных целей. Возвращаясь к примеру с UI: есть универсальный виджет HP который можно повесить как на игрока, так и на противника
Виджет обновляет свою информацию путём функции обратного вызова на целевом экторе. Т.е. у эктора меняется HP, вызывается диспатчер OnHealthChanged, на который UI заранее заботливо подписался.
Но тут есть интересный момент, как я сказал - виджет универсальный. он умеет показывать здоровье игрока, npc и даже деревянных ящиков на уровне. Но это 3 разных класса, не имеющих общих предков кроме AActor.
Значит, в каждом из них свой уникальный диспатчер, сигнализирующий об изменении HP
Далее, плохой вариант: UI пытается понять к какому классу принадлежит его эктор, делает каст и подписывается на конкретный делегат
Хороший вариант: есть, к примеру, интерфейс, возвращающий этот делегат. Эти 3 класса его имплементируют. UI через интерфейс получает ссылку на этот делегат и подписывается на него (это условный пример, в BP так делать нельзя). Таким образом он не знает какой класс на другом конце, ему достаточно знать, что там есть данная функция, всё остальное его не волнует
Ещё более удобный вариант для анрила: ищем в экторе компонент, отвечающий за хп (Если такой имеется), подписываемся на его делегат. Будет работать с любым эктором, в котором есть такой компонент. И не надо тогда делать интерфейс