Intereting Posts
Поле редактирования мягкой клавиатуры Android Hibernate @OneToMany join table throws StackOverflowException Как добавить пользовательские группы просмотра в Anko DSL? Создание списка из ResultSet Нулевая безопасность в старых библиотеках Java, используемых в проектах Kotlin Как исправить подпись обобщенного метода расширения в kotlin для разрешения «Ошибка вывода типа» в kotlin установить UserDefaultsKeys (swift) в kotlin Kotlin Decompiler генерирует ошибочный код – можно ли предотвратить? Почему неразрешенная ссылка на попытку доступа к постоянным значениям? Установка проекта Android Kotlin не выполняется с помощью INSTALL_FAILED_DEXOPT Kotlin: Как запустить функцию с задержкой с помощью функции расширения Может ли объект класса, созданный «на лету» в Котлине, иметь конструктор? Определение размера для настраиваемого типа массива в Android Kotlin Можно ли указать статическую функцию в интерфейсе Kotlin? Не удается профилировать приложение Android в Android Studio

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

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