我刚刚开始探索Kotlin,并且对它超出Java核心动态绑定(bind)/调度语义的范围感到好奇。

假设我写的代码看起来像这样:

动物类{
有趣的add(x:Animal)= Animal()
}

对象马:动物
对象驴:动物
M子:动物

有趣的Horse.add(x:Horse)= Horse()
有趣的Horse.add(x:Donkey)= Mule()

fun main(args:Array){
val h:动物=马
val d:动物=驴
val child = h + d
}

基于以上代码,我期望发生什么?我在运行时是否由于Horse不实现add(Animal)而失败?是否可以在上述性质的调用中准确地区分它们,所比较的值的编译时类型为Animal(至少按书面规定),但其运行时类型更具体?如果我们使用var而不是val,它会改变任何东西吗?

提前致谢。

编辑:修改后的核心代码-我看到第一响应者强调的问题,我并没有直截了当。显然,我实际上并没有对此进行编译,但我仍然在概念上进行探索。

另外,我将在实际的编译器中试一试,但是我担心在某些情况下它会工作,而在某些情况下,它并不是基于我不完全了解的某些标准。我找不到关于如何在Kotlin中实现动态调度的参考文档(就此而言,也不确定是否适用于Java);几个月前,我写了一些东西,我认为它可以基于JVM文档工作,但是它没有不会,而我从来没有机会探索确切的原因。

无论如何再次感谢!

最佳答案

因此,这是实际编译的代码版本:

fun main(vararg args: String) {
    val h:Animal = Horse
    val d:Animal = Donkey
    val child = h + d
    println(child)
}

open class Animal {
    fun plus(x:Animal) = Animal()
}

object Horse : Animal()
object Donkey : Animal()
object Mule : Animal()

fun Horse.plus(x:Horse) = Horse
fun Horse.plus(x:Donkey) = Mule

结果为“Animal @ 1906bcf8”。

据我了解,扩展方法(即Horse.plus(x:Horse)Horse.plus(x:Donkey))是静态分配的。这是因为它们基本上被编译为与以下Java代码相同的字节代码:
static Horse plus(Horse $receiver, Horse x) {
    return Horse.INSTANCE;
}

顺便说一句,这与Java 8中的默认方法有很大的不同,它们是根据运行时类型动态调度的,并且可以被覆盖。

08-18 17:38