Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/kotlin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Inheritance kotlin类扩展解析父类';在列表上下文中使用时,使用s值而不是childs_Inheritance_Kotlin_Class Extensions - Fatal编程技术网

Inheritance kotlin类扩展解析父类';在列表上下文中使用时,使用s值而不是childs

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

我正在处理Kotlin(1.3.20)中的类扩展,在扩展同一属性上的父类和子类,然后使用这些属性的实例时遇到了一个问题

基本上,子类的实例返回父类属性的值集,我不明白这是为什么。 我希望下面代码中的第16行返回“ext special thing”,但它确实返回“ext thing”,即使b[1]中的实例肯定是ExtSpecialThing类型

我怀疑原因是扩展属性/扩展功能在引擎盖下工作的方式(顺便说一句:扩展功能也存在此问题);但我不是这方面的专家

tl;dr:第16行失败。。。为什么?

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) 

这意味着当我循环一个包含未知内容的列表时,除非我手动检查并指定所有可能项目类的强制转换,否则这将永远不会起作用?是的,扩展函数恐怕不能很好地处理多态性