Kotlin: ¿puedes explicar las funciones de extensión de miembros?

Mi código es el siguiente:

open class Particle class Electron : Particle() open class Element(val name: String) { open fun Particle.react(name: String): Unit { println("$name is reacting with a particle") } open fun Electron.react(name: String): Unit { println("$name is reacting with an electron") } fun react(particle: Particle): Unit { particle.react(name) } } fun main(args: Array<String>) { val selenium = Element("Selenium") selenium.react(Particle()) selenium.react(Electron()) } 

Mi salida es la siguiente:

El selenium está reactjsndo con una partícula

El selenium está reactjsndo con una partícula

No entiendo: ¿por qué la segunda salida no debería ser "El selenium está reactjsndo con un electrón"?

Si agregué otra subclass

 class NobleGas(name: String) : Element(name) { fun react(particle: Electron): Unit { particle.react(name) } } fun main(args: Array<String>) { val neon = NobleGas("Selenium") neon.react(Particle()) neon.react(Electron()) } 

La salida es: el selenium está reactjsndo con una partícula El selenium está reactjsndo con un electrón

¿Por qué la segunda salida es "El selenium está reactjsndo con un electrón"?

    Las funciones de extensión comstackn las llamadas a funciones estáticas y, por lo tanto, el método a llamar está determinado por los types estáticos de time de compilation en lugar de los types de time de ejecución de los objects.

    No hay un despacho dynamic aquí como el que se obtiene cuando se llama a un método anulado en una subclass y se obtiene esa implementación en lugar de lo que está en la class base. Básicamente, no hay funciones de extensión primordiales.

    Para el ejemplo específico: en time de compilation, dentro de la function react(particle: Particle) , el tipo de particle estática es solo Particle en time de compilation, por lo que siempre llamará a la function de extensión definida en la class Particle .