Проблема с сеттером

Рейтинг: 0Ответов: 1Опубликовано: 25.08.2023
open class NumInc(var number: Int, step: Int) {
    constructor(): this(0, 1)
    var step = step
        set(value) {
            field = if (value != 0)
                value
            else
                1
        }
    open fun inc() { number += step }
    open fun dec() { number -= step }
}
class NumDouble(number: Int, step: Int): NumInc(number, step) {
    override fun inc() { number += step * 2}
    override fun dec() { number -= step * 2}
}
fun main() {
    val a = NumDouble(3, 0)
    val b = NumInc(3, 0)
    a.inc()
    b.inc()
    println(a.number)
    println(b.number)
}

По идее, в b step должен поменяться с 0 на 1, и вывод должен быть "3 4", а вывод - "3 3".

Ответы

▲ 0
  1. У параметра step в конструкторе класса NumInc нет ни var:, ни val:

    open class NumInc(var number: Int, step: Int) {
    

    потому Kotlin не изменит его автоматически в свойство (property).

    Он остается только параметром, и как такой будет неизменяемым (immutable).

     

  2. Командой

     var step = step
    

    вы определяете свойство этого класса, т.е. что-то другое, доступное и изменяемым из вне в виде объект.step. (Тем самым вы перекрываете имя step как имя параметра).

     

  3. Затем вы командой

         set(value) {
    

    определяете сеттер для этого свойства, но его код не исполняется немедленно, как вы, вероятно, думали; он «спит», ожидая на присвоения в виде

    объект.step = что-то
    

    когда он реально запускается и выполняется.


Решение:

Достаточно только добавить команду

b.step = 0

после создания объекта b в функции main(), чтобы ваш код делал то, чего вы хотели:

fun main() {
    val a = NumDouble(3, 0)
    val b = NumInc(3, 0)
    b.step = 0                # только здесь запускается ваш сеттер
    a.inc()
    b.inc()
    println(a.number)
    println(b.number)
}

Вывод:

3
4