Kotlin 覆盖成员集并获取
Kotlin override member set and get
有没有人知道更好的方法来监听自己基地内的成员变化class?
class FOO {
val t: String
}
class BOO: FOO {
fun x(val t: String) {
// notify when t was changed
}
}
在我看来,带有 Observer 的 JavaRx 就足够了。 Kotlin Delegate 不适用于继承(或者我还找不到方法)。我想出的最好办法是在 "BOO" 中覆盖 "t" 的 setter 和 getter。但这有点尴尬,因为 "Why should i overwrite a member?" 或 "Why do i have to define set and get when i just need 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
}
}
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()
,
参见 Language reference:
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,但这只是一个额外的行。
有没有人知道更好的方法来监听自己基地内的成员变化class?
class FOO {
val t: String
}
class BOO: FOO {
fun x(val t: String) {
// notify when t was changed
}
}
在我看来,带有 Observer 的 JavaRx 就足够了。 Kotlin Delegate 不适用于继承(或者我还找不到方法)。我想出的最好办法是在 "BOO" 中覆盖 "t" 的 setter 和 getter。但这有点尴尬,因为 "Why should i overwrite a member?" 或 "Why do i have to define set and get when i just need 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
}
}
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()
,
参见 Language reference:
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,但这只是一个额外的行。