鉴于以下场景,有一些基类应该简单地委托给派生类,为什么派生类中的两个apply()
方法永远不会被调用?
要演示:在main
函数中,我将使用两个事件调用apply
。在抽象类中,我将apply
这两个事件。基类中有一个通用的apply(Event)
函数,但应该忽略它,并通过动态调度转到派生类中的各个apply(EventOne)
和apply(EventTwo)
方法。
我也尝试过这种方法,每个apply
方法返回自己,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)
}
}
...
}
答案 0 :(得分:2)
因为动态调度仅适用于this
,即方法覆盖。它不适用于方法的参数;方法重载在编译时静态解析。
您遇到的问题传统上是通过visitor pattern等问题解决的。另一种方法是根据参数的运行时类型执行查找,Kotlin允许您通过when
expression更优雅地执行查找。