Override getter force to override setter too


#1

I want override a getter of property

 class A {
   var foo : Bar = Bar()
}


class B : {
  override var foo : Bar 
     get() {
        thing();
       super.foo
      }
}

But this throw error: Or initialize foo in B or add setter.
If initialize the compiler create a new variable foo in B (duplicate), so I need create a setter that only call to parent


#2

Yes, this is correct. We haven’t found this to be much of a problem in practice, but it’s possible that we’ll improve this later. Please feel free to watch/vote for https://youtrack.jetbrains.com/issue/KT-12996


#3

will this not solve the problem of initialization? does it still create duplicate variable?

override var foo: Bar = super.foo
        get() {
            initializeSomething()
            return super.foo
        }

#4

If you initialise like this then, yes it will (initialising to super.foo is pointless). The initializer does not use the setter, and as the underlying field is always private overriding is not able to initialise it to a different value. If you want to set the value to a different one on subclass class instantiation use an init block to actually set it (keeping in mind that this will involve the setter).

override var foo:Bar
  get() {
    initializeSomething()
    return super.foo
  }

init { foo = newInitialValue }

#5

I’d have thought that what @miguelangellv needs is this, which should compile and run OK and doesn’t need an initializer:

open class A {
    open var foo: Bar = Bar()
}

class B : A() {
    override var foo: Bar
        get() {
            thing()
            return super.foo
        }
        set(value) {              
            super.foo = value
        }
}

#6

Yes. But that is being tracked at youtrack.com (KT-12996). I was trying to understand if the initialization like I did above could help him.


#7

Since you say you haven’t found this much of a problem in practice I thought you might find my experience interesting.

I just ran into this after I migrated a largish Android project to Kotlin. There were a handful of overridden fields, some with only getters, some with only setters. Android Studio doesn’t give any indication (that I am aware of – maybe I missed something?) that I might need to override both getter and setter in order to call super, it just said “Property must be initialized.” So I did, and then I had a lot of fun hunting down the bugs resulting from the fact that the super’s getter or setter wasn’t called.

The fact that you have to create both getter and setter in order to call super is only a mild inconvenience, but the fact that you can seemingly side-step this requirement by adding initialization, AND that this introduces (from my perspective, anyway…) the side effect that the super getter/setter won’t be called is pretty surprising, IMHO.