Intereting Posts
Как создать заголовок вложенного / разделенного столбца с помощью TornadoFx? Не удается написать основной конструктор класса Activity в Kotlin в Android Как получить / положить Kotlin Внутренняя карта или Карта карты Класс не найден, пустой набор тестов в androidTest с использованием Android Studio 3.0.1, Room, Kotlin Чтение вывода от exec kotlin kotlin unreachable code при использовании finally и enum Как проверить состояние, как i <J in for loop kotlin Нельзя использовать значение argb color int в Kotlin? Отправлять данные, полученные из Parse SDK в одном классе приложений, в Activity in android Анимационный набор, эффект встряхивания IllegalStateException в контексте Kotlin не должно быть null Невозможно повторно назначить локальные переменные Невозможно поймать бросок исключения после отмены Kotlin coroutine Android-сборка завершилась неудачей с помощью котлин-отражения и пролога Является ли тип неявного свойства одинаковым с явным типом свойства?

Kotlin переопределяет набор элементов и получает

Кто-нибудь знает лучший способ прослушать изменения членов в рамках собственного базового класса?

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

На мой взгляд, JavaRx с Observer будет много. Kotlin Delegate не работает с наследованием (или я еще не мог найти способ). Лучшее, что я придумал, это переопределить сеттер и геттер «t» в «BOO». Но это немного неудобно из-за этого: «Зачем мне переписывать участника?» или «Почему я должен определить набор и получить, когда мне просто нужно установить?»

Итак, мое решение пока:

 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 } } 

Solutions Collecting From Web of "Kotlin переопределяет набор элементов и получает"

 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 } } 

Единственный недостаток, который я вижу здесь, – это необходимость явно переопределить геттер, но это всего лишь одна дополнительная строка.