Inheritance kotlin类扩展解析父类';在列表上下文中使用时,使用s值而不是childs
我正在处理Kotlin(1.3.20)中的类扩展,在扩展同一属性上的父类和子类,然后使用这些属性的实例时遇到了一个问题 基本上,子类的实例返回父类属性的值集,我不明白这是为什么。 我希望下面代码中的第16行返回“ext special thing”,但它确实返回“ext thing”,即使b[1]中的实例肯定是ExtSpecialThing类型 我怀疑原因是扩展属性/扩展功能在引擎盖下工作的方式(顺便说一句:扩展功能也存在此问题);但我不是这方面的专家 tl;dr:第16行失败。。。为什么?Inheritance kotlin类扩展解析父类';在列表上下文中使用时,使用s值而不是childs,inheritance,kotlin,class-extensions,Inheritance,Kotlin,Class Extensions,我正在处理Kotlin(1.3.20)中的类扩展,在扩展同一属性上的父类和子类,然后使用这些属性的实例时遇到了一个问题 基本上,子类的实例返回父类属性的值集,我不明白这是为什么。 我希望下面代码中的第16行返回“ext special thing”,但它确实返回“ext thing”,即使b[1]中的实例肯定是ExtSpecialThing类型 我怀疑原因是扩展属性/扩展功能在引擎盖下工作的方式(顺便说一句:扩展功能也存在此问题);但我不是这方面的专家 tl;dr:第16行失败。。。为什么? i
import kotlin.test.*
fun main (args : Array<String>) {
assertEquals("ext-special-thing", ExtSpecialThing().prop)
var a = listOf(ImplThing(), ImplSpecialThing())
assertTrue(a[0] is ImplThing)
assertTrue(a[1] is ImplSpecialThing)
assertEquals("impl-thing", a[0].prop)
assertEquals("impl-special-thing", a[1].prop)
var b = listOf(ExtThing(), ExtSpecialThing())
assertTrue(b[0] is ExtThing)
assertTrue(b[1] is ExtSpecialThing)
assertEquals("ext-thing", b[0].prop)
assertEquals("ext-special-thing", b[1].prop) // fails ... why?
}
// ======================================
open class ImplThing () {
open val prop : String = "impl-thing"
}
class ImplSpecialThing : ImplThing() {
override val prop : String = "impl-special-thing"
}
// -------------------------------------
open class ExtThing () {}
class ExtSpecialThing : ExtThing () {}
val ExtThing.prop : String get() = "ext-thing"
val ExtSpecialThing.prop : String get() = "ext-special-thing"
导入kotlin.test*
趣味主线(args:Array){
assertEquals(“ext特殊事物”,ExtSpecialThing().prop)
var a=listOf(ImplThing(),ImplSpecialThing())
assertTrue(a[0]正在执行)
assertTrue(a[1]正在执行)
assertEquals(“impl thing”,一个[0].prop)
assertEquals(“impl特殊事物”,a[1]。道具)
var b=listOf(ExtThing(),ExtSpecialThing())
assertTrue(b[0]是ExtThing)
assertTrue(b[1]是ExtSpecialThing)
assertEquals(“外部事物”,b[0]。属性)
assertEquals(“ext special thing”,b[1].prop)//失败……为什么?
}
// ======================================
开放类请求(){
open val prop:String=“impl thing”
}
类ImplSpecialThing:implshing(){
override val prop:String=“impl special thing”
}
// -------------------------------------
开放类ExtThing(){}
类ExtSpecialThing:ExtThing(){}
val ExtThing.prop:String get()=“ExtThing”
val ExtSpecialThing.prop:String get()=“ext special thing”
官方文件对此进行了描述:
我们想强调的是,扩展函数是静态调度的,也就是说,根据接收器类型,它们不是虚拟的。这意味着调用的扩展函数由调用函数的表达式的类型决定,而不是由运行时计算该表达式的结果的类型决定
因此,这意味着以下几点将使您的测试成功:
assertEquals("ext-special-thing", (b[1] as ExtSpecialThing).prop)
这意味着当我循环一个包含未知内容的列表时,除非我手动检查并指定所有可能项目类的强制转换,否则这将永远不会起作用?是的,扩展函数恐怕不能很好地处理多态性