Kotlin覆盖成员设置并获取

有没有人知道更好的方式来听取自己的基类内的成员变化?

class FOO { val t: String } class BOO: FOO { fun x(val t: String) { // notify when t was changed } } 

在我看来,与观察员JavaRx会很多。 科特林代表不能继承工作(或者我找不到方法)。 我想出的最好的是在“BOO”中覆盖“t”的setter和getter。 但是这个有点尴尬,因为这个“为什么我应该覆盖一个成员?” 或者“为什么我只需要定义一个集合,然后得到什么时候我只需要设置?”

所以我的解决方案:

 import kotlin.properties.Delegates fun main(args: Array<String>) { var foo = FOO() foo.t = "foo" foo.printT() var boo = BOO() boo.t = "boo" boo.printT() } open class FOO () { open var t: String? = "origin" set(value) { println("\t origin setter is called") field = String() + value // create a copy (original it is not a String :D) } get() { println("\t origin getter is called") return field } fun printT() = println(t) } class BOO (): FOO () { override var t: String? set(value) { // thats all what i need println("\t overwritten setter is called") super.t = value // execute origin setter } get() { println("\t overwritten getter is called") return super.t } } 

 open class FOO { var t: String = "origin" set(value) { field = value x(t) } open fun x(t: String) { println("FOO: t=$t") } } open class BOO : FOO() { override fun x(t: String) { super.x(t) println("BOO: t=$t") } } 

更新:

我个人认为它看起来有点奇怪,但是如果你以后不需要重写任何成员(字段或方法),那么你可以使你的onChange方法属性:

 open class FOO(val onChange: (t: String) -> Unit = FOO.defaultOnChange) { companion object { val defaultOnChange: (t: String) -> Unit = { println("FOO: t=$it") } } var t: String = "origin" set(value) { field = value onChange(t) } } open class BOO : FOO({ defaultOnChange(it); println("BOO: t=$it") }) 

类似的方法,但与Delegates.observable() ,请参阅语言参考 :

 import kotlin.properties.Delegates open class UserBase { var name: String by Delegates.observable("<no name>") { prop, old, new -> println("$old -> $new") onChange(new) } // could be abstract, if class is abstract open fun onChange(v: String?) {} } class User : UserBase() { override fun onChange(v: String?) { println("I was changed in my base class: ${v}") } } fun main(args: Array<String>) { val user = User() user.name = "first" user.name = "second" } 

为什么不只是简单的压倒一切? 像这样:

 open class FOO () { open var t: String = "origin" fun printT() = println(t) } class BOO (): FOO () { override var t: String get() = super.t set(value) { // thats all you need println("\t overwritten setter is called") super.t = value } } 

我在这里看到的唯一缺点是需要显式重写getter,但这只是一个额外的行。

Interesting Posts