Maharkus
Maharkus

Reputation: 2898

How do I override a var in a Kotlin class correctly?

I am trying to overwrite a value in a class. I have the following code:

open class Balloon() {
    open var textSize: Float = 20f
    init {
        Log.i("textSize", textSize.toString())
    }
}
    
class BigBalloon(): Balloon() {
    override var textSize = 30f
}

However, the Log prints out these values:

enter image description here

First Log is from Balloon(), second one is from BigBalloon(). How can it print 0.0 when I overwrote it as 30? Did I implement all of this incorrectly?

Upvotes: 3

Views: 1017

Answers (2)

Pawel
Pawel

Reputation: 17248

Accessing abstract methods (in this case getTextSize) in constructor is generally discouraged since it might lead to artifacts like yours.

BigBaloon property override actually does two things:

  1. creates new internal field - BigBaloon.textSize
  2. overrides textSize getter and setter to access that field

It's a bit counter intuitive but it does NOT modify value of Baloon.textSize field, it's left untouched and inaccessible since getter/setter no longer use it.

Your issue is when BigBaloons parent Baloon is being initialized it accesses BigBaloon.textSize which is NOT initialized at this point so it returns zero.

Upvotes: 5

Animesh Sahu
Animesh Sahu

Reputation: 8096

Kotlin initialization order is not how you understand it, the init block of the Base (Balloon) class is called before the override is done. It is explained better in this answer. And here's the initialization order given in Kotlin docs.

Put the property into primary constructor as:

Balloon(var textSize: Float = 20f) {
    // ...
}

And when you want to change it, just delegate it to the constructor:

class BigBalloon: Balloon(30f)

Upvotes: 3

Related Questions