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
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
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).
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.