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,但这只是一个额外的行。