Делегирование методов производных классов с помощью динамической отправки

Учитывая приведенный ниже сценарий, где есть некоторый базовый класс, который должен просто делегировать производным классам, почему два метода apply() в производных классах никогда не вызываются?

Чтобы продемонстрировать: в main функции я назову apply два события. В абстрактном классе я буду apply оба этих события. В базовом классе существует общая функция apply(Event) , но ее следует игнорировать и через динамическую отправку обращаться к apply(EventOne) и apply(EventTwo) в производном классе.

Я также пробовал это, когда каждый индивидуальный метод приложения возвращался сам, а функция applyFromHistory использовала вместо этого fold , но получала тот же результат.

 fun main(args: Array<String>) { val subject = SomeAggregate() subject.applyFromHistory(listOf( EventOne(123), EventTwo("foobar") )) } sealed class Event data class EventOne(val id: Int) : Event() data class EventTwo(val content: String) : Event() abstract class AggregateRoot( private val events : MutableList<Event> = mutableListOf() ) { fun applyFromHistory(history: List<Event>) { history.forEach { apply(it) } } fun apply(event: Event) { /* does nothing */ } } class SomeAggregate(var id: Int = 0, var content: String = "") : AggregateRoot() { fun apply(event: EventOne) { id = event.id } fun apply(event: EventTwo) { content = event.content } } 

Я надеялся уйти от:

 abstract class AggregateRoot(... { ... abstract fun apply(event: Event) } class SomeAggregate(... : AggregateRoot() { ... override fun apply(event: Event) { when(event) { is EventOne -> apply(event) is EventTwo -> apply(event) } } ... } 

Поскольку динамическая отправка применяется только к this , то есть к переопределению метода. Это не относится к аргументам метода; перегрузки метода решаются статически во время компиляции.

Проблема, с которой вы сталкиваетесь, традиционно решается такими вещами, как шаблон посетителя . Альтернативой является поиск в зависимости от типа времени выполнения аргумента, который Kotlin позволяет вам делать более элегантно с помощью выражения when .