¿Cuáles son los límites en el despacho dynamic / doble en Kotlin?

Estoy empezando a explorar Kotlin, y tengo curiosidad sobre hasta qué punto se mueve más allá de la semántica dinámica central de enlace / despacho de Java.

Digamos que escribo un código que se ve así:

     class Animal {
         añadir diversión (x: Animal) = Animal ()
     }

     object Caballo: Animal
     object Burro: Animal
     object Mule: Animal

     diversión Horse.add (x: Horse) = Horse ()
     diversión Horse.add (x: Donkey) = Mule ()

     divertido main (args: Array) {
         val h: Animal = Caballo
         val d: Animal = Burro
         val child = h + d
     }

Basado en el código anterior, ¿qué puedo esperar que ocurra? ¿Recibo un error en el time de ejecución porque Horse no implementa add (Animal)? ¿Puede diferenciarlos con precisión en las llamadas de la naturaleza anterior, donde el tipo de time de compilation de los valores que se comparan era Animal (al less, como está escrito) pero sus types de time de ejecución eran más específicos? ¿Cambia algo si usamos var en lugar de val?

Gracias por adelantado.

EDITAR: Código central modificado – Veo el problema que resaltó el primer respondedor, no estaba pensando correctamente. Claramente, no lo he comstackdo, todavía estoy explorando a nivel conceptual.

Además, le daré una oportunidad en el comstackdor real, pero me preocupa que haya situaciones en las que funcione y otras en las que no se base en algunos criterios que no entiendo completamente. No pude encontrar documentos de reference sobre cómo se implementa el despacho dynamic en Kotlin (tampoco estoy seguro sobre Java, para el caso, escribí algo hace unos meses que pensé que funcionaría basado en documentos de JVM, pero no lo hice). 't, y nunca tuve la oportunidad de explorar exactamente por qué).

De todos modos, ¡gracias de nuevo!

Así que aquí hay una versión de tu código que realmente comstack:

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 

El resultado es "Animal @ 1906bcf8".

Por lo que yo entiendo, los methods de extensión, es decir, Horse.plus(x:Horse) y Horse.plus(x:Donkey) , se envían estáticamente. Esto se debe a que están comstackdos básicamente con el mismo código de bytes que el siguiente código Java:

 static Horse plus(Horse $receiver, Horse x) { return Horse.INSTANCE; } 

Por cierto, esta es una gran diferencia con respecto a los methods pnetworkingeterminados en Java 8, que se envían dinámicamente en function del tipo de time de ejecución y se pueden sobrescribir.

Este código no es comstackble en absoluto, porque Animal no tiene ningún operador "+".

Si permitieran utilizar los methods Horse "+" en un Animal, obtendrías errores de time de ejecución, que kotlin / java / etc. trata de prevenir

Kotlin no trabajará con el tipo de time de ejecución para resolver los methods y esas cosas, porque hay posibilidades de producir errores de time de ejecución.

¿Qué pasa si otro hilo cambia a Animal to a Mule mientras tanto, la línea / time exacto cuando el otro hilo cambia Animal no es determinista, por lo que esto podría conducir a errores de time de ejecución.

Val o var no cambia nada en esta situación.

  • Extender RxJava Observable en Kotlin con eliminación adecuada
  • ¿Podemos definir nuestros accesadores sin un valor init?
  • La cadena cruda de Kotlin arroja un error en blanco
  • Dependencia circular (Voronoi Halfedge)
  • Método simulado que no devuelve el valor de la variable test-local
  • ¿Cómo puedo get una reference a Kotlin KClass por nombre cuando no se ejecuta en la JVM?
  • Problema de reference no resuelto de Kotlin
  • Asynctask múltiples requestes de URL consecutivas en Android
  • Kotlin Assign Delegate después de statement de variable
  • Cómo implementar un getter abstracto con propiedad
  • Comtesting si mi actividad está en MultiWindowMode o no está usando Kotlin