通过动态分派委派派生类方法

鉴于下面的情况,哪里有一些基类应该简单地委托给派生类,那么为什么派生类中的两个apply()方法永远不会被调用?

为了演示:在main函数中,我将调用两个事件来apply 。 在抽象类中,我将apply这两个事件。 在基类中有一个通用的apply(Event)函数,但是它应该被忽略,并且通过动态调度去派生类中的apply(EventOne)apply(EventTwo)方法。

我也尝试过每个单独的apply方法返回自己,而applyFromHistory函数使用fold来代替,但得到了相同的结果。

 fun main(args: Array) { 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 = mutableListOf() ) { fun applyFromHistory(history: List) { 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 ,即方法重写 。 它不适用于方法的论点; 方法重载是在编译时静态解析的。

你面临的问题传统上是通过访问者模式来解决的。 另一种方法是根据参数的运行时types执行查找,Kotlin允许您通过whenexpression式更加优雅地进行查找。