Inheritance Kotlin重写成员集并获取

Inheritance Kotlin重写成员集并获取,inheritance,setter,kotlin,overwrite,Inheritance,Setter,Kotlin,Overwrite,有人知道在自己的基类中监听成员更改的更好方法吗 class FOO { val t: String } class BOO: FOO { fun x(val t: String) { // notify when t was changed } } 在我看来,JavaRx与Observer将是非常重要的。Kotlin委托无法处理继承(或者我还找不到方法)。我想出的最好办法是在“BOO”中超越“t”的setter和getter。但这有点尴尬,因为“为什

有人知道在自己的基类中监听成员更改的更好方法吗

class FOO {
    val t: String
}

class BOO: FOO {
    fun x(val t: String) {
        // notify when t was changed 
    }
}
在我看来,JavaRx与Observer将是非常重要的。Kotlin委托无法处理继承(或者我还找不到方法)。我想出的最好办法是在“BOO”中超越“t”的setter和getter。但这有点尴尬,因为“为什么我要覆盖一个成员?”或者“为什么我需要定义set和get,而我只需要set?”

到目前为止,我的解决方案是:

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
    }
}
导入kotlin.properties.Delegates
趣味主线(args:Array){
var foo=foo()
foo.t=“foo”
foo.printT()
var boo=boo()
boo.t=“boo”
boo.printT()
}
开放类FOO(){
打开变量t:字符串?=“原点”
设置(值){
println(“\t调用原点设置器”)
field=String()+value//创建副本(原始副本不是字符串:D)
}
得到(){
println(“\t调用原始getter”)
返回场
}
fun printT()=println(t)
}
类BOO():FOO(){
重写var t:String?
设置(值){
//这就是我所需要的
println(“\t调用覆盖的setter”)
super.t=值//执行原点设置器
}
得到(){
println(“\t重写的getter被调用”)
返回super.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") })

类似的方法,但使用的是
委托.observable()
, 见:

导入kotlin.properties.Delegates
开放类用户库{
变量名称:代理字符串。可观察(“”{prop,旧,新->
println(“$old->$new”)
onChange(新)
}
//如果类是抽象的,则可以是抽象的
打开有趣的onChange(v:String?{}
}
类用户:UserBase(){
覆盖有趣的onChange(v:String?){
println(“我在基类中被更改:${v}”)
}
}
趣味主线(args:Array){
val user=user()
user.name=“第一”
user.name=“第二个”
}

为什么不直接重写?就像这里:

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

您好,谢谢您的回答。是的,这是一条直截了当的道路,我也考虑过这一点。但这将增加api中的方法计数,因此3个成员将有3个onChangelistener@Mario我以为你在试图避免需要重写
t
。“我为什么要覆盖一个成员?”在这里你不需要(除非你也试图避免覆盖一个成员方法)。“为什么我必须定义集合并在我只需要集合的时候获取?”在这里,你不需要定义集合,只需要定义集合。这看起来很奇怪,可以尝试一下。我像这样重写我的类,并查看类对象的可见性范围。为什么Unit=FOO.defaultOnChange?-我知道结果,但不知道它是如何正确工作的,尽管它不是
Unit=…
,而是
(t:String)->Unit=FOO.defaultOnChange
。是的。。。我只是添加了注释并覆盖了getter setter以供学习。无论如何,我不明白为什么kotlin强迫我覆盖getter。。。如果我不这样做,科特林将以一种完全不同的方式来处理BOO.t,而我预计是这样
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 
    }
}