Учитывая приведенный ниже сценарий, где есть некоторый базовый класс, который должен просто делегировать производным классам, почему два метода 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
.