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
如何将实现委托给Kotlin中的属性?_Kotlin - Fatal编程技术网

如何将实现委托给Kotlin中的属性?

如何将实现委托给Kotlin中的属性?,kotlin,Kotlin,Kotlin使我能够通过委托给主构造函数参数来实现接口,如下所示: class Foo(xs : ArrayList<Int>) : List<Int> by xs { } class-Foo(xs:ArrayList):按xs{}列出 但这向用户展示了支持实现者。授权给匿名者似乎也没问题: class Foo() : List<Int> by ArrayList<Int>() { } class Foo():按ArrayList()列出({

Kotlin使我能够通过委托给主构造函数参数来实现接口,如下所示:

class Foo(xs : ArrayList<Int>) : List<Int> by xs { }
class-Foo(xs:ArrayList):按xs{}列出
但这向用户展示了支持实现者。授权给匿名者似乎也没问题:

class Foo() : List<Int> by ArrayList<Int>() { }
class Foo():按ArrayList()列出({}
这隐藏了实现细节,但我们失去了对接口未提供的特性的访问,在本例中,这是可变的

因此,我希望将实现委托给不在主构造函数中的属性。我想要的和

class Foo() : List<Int> by xs {
    val xs : List<Int> = ArrayList<Int>()
}
class Foo():按xs列出{
val xs:List=ArrayList()
}
它不能编译


是否可以在类主体中显式定义属性,并且仍然能够将实现委托给它?

这在当前是不可能的。在类构造之前,
by
-子句中的表达式只计算一次,因此不能引用该类的符号

虽然Kotlin 1.0中几乎肯定不支持它,但是有一种方法允许这样做

一个有趣的解决方法是将您希望成为委托的属性改为具有默认值的构造函数参数。这样,它就可以在
by
-子句和类主体中访问:

class Foo(val xs: List<Int> = ArrayList<Int>()) : List<Int> by xs {
    fun bar() {
        println(xs)
    }
}
class-Foo(val-xs:List=ArrayList()):按xs列出{
趣味酒吧(){
println(xs)
}
}

请记住,
xs
中的
xs
在这里仍然只计算一次,因此即使
xs
var
属性,也只会使用构造函数中提供的默认值。这不是一个通用的解决方案,但有时会有所帮助。

根据Alexander Udalov的答案,我提出了一个使用私有基类的解决方案

private open class FooBase(protected val xs : MutableList<Int>) : List<Int> by xs { }

class Foo() : FooBase(ArrayList()) {
    fun bar() {
        xs.add(5)
    }
}

我很好奇为什么会发生这样的反对。在这种情况下,我也会收到同样的通知。动机是什么?
class Foo private constructor(private val xs: ArrayList<Int>) : List<Int> by xs {
    constructor() : this(ArrayList<Int>()) { }
}