繁体   English   中英

覆盖子类型Kotlin / Java中的函数类型

[英]Override a function type in sub type Kotlin/Java

我有这个界面:

// Interface for any simulation that is integrated against dt
interface SimulationState {
    fun integrate(totalTime: Long, deltaTime: Long) : SimulationState
    fun interpolate(alpha: Double, previousState: SimulationState) : SimulationState
    fun preRender() : Collection<Pair<Int, Int>>
}

在这种情况下,实现与我的问题无关。 问题是我可以覆盖子类型中的函数类型吗? 下面是一个示例,该示例未编译; 因此,我提出这个问题的原因。

interface ShipState : SimulationState {
    // Still in abstract, just hope I can somehow override the function type...
    override fun integrate(totalTime: Long, 
                           deltaTime: Long,
                           asteroidVectors: Collection<Pair<Double, Double>>) : SimulationState
}

希望上面公认的未编译代码能清楚表明我的意图。 Java / Kotlin是否可能? 如果是这样,我将如何处理?

JVM对象结构具有指向可用方法表的内部指针。 当您调用对象的方法时,JVM访问该表(将其称为vtable),如果找到了方法,它将执行该表。 但是,如果那里找不到方法怎么办? 然后,它尝试在父类中找到此方法。 可以在编译期间检测到这些访问,这有助于避免在运行时调试时出现非常复杂的问题。

现在,让我们想象您的例子是可能的。 您有一个实现ShipState的类,并通过它实现了SimulationState 您从接口ShipState (带有3个参数的接口)实现方法integrate

但是等等,您的对象仍然是SimulationState类型,对吗? 现在,让我们假设您想创建一组仿真并以单一方式处理它们:

val simpleSimulation = SimulationStateImpl() //imaginary implementation of base interface
val shipSimulation = ShipSimulationImpl() // again imaginary implementation
val simulations = listOf<SimulationState>(simpleSimulation, shipSimulation)
simulations.forEach { it.integrate(totalTime = 100, deltaTime = 50) }

接下来发生什么? 在第一次迭代中,一切都很好。 当您在simpleSimulation JVM访问上调用integrate ,它是vtable,查找具有两个参数的integrate实现并调用它。 精细。

在第二次迭代中,JVM访问对象shipSimulation vtable。 它尝试解析具有两个参数的方法integrate ,但找不到它。 好吧,下一步该怎么做? 有类似的方法具有三个参数,我们应该调用它吗? 如果是,我们需要传递哪个参数? null吗? 为什么? 如果您的类似方法多了5个参数,该怎么办? 编译器和运行时无法解决此问题,这就是失败的原因。

就Java / Kotlin OOP而言,您要做的不是override 您只需将新方法添加到新接口,巧合的是,该接口看起来与另一个接口非常相似。 但是,这种巧合并不意味着它是相同的方法。

请看一下这篇精彩的文章 ,其中详细介绍了主题。

可能您不需要override而是overload

如果是,则从派生接口中删除关键字override

如果需要override (将使用多态),则两个函数必须具有相同的签名。

无法覆盖该功能:

(Long, Long) -> SimulationState

具有功能:

(Long, Long, Collection) -> Unit

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM