open class Super {
open var name : String = \"Name1\"
init {
println(\"INIT block fired with : $name\")
name = name.toUpperCase()
p
Essentially, because you tell Kotlin that your subclass is going to be defining name
now, it is not defined when the init
block in Super
is executed. You are deferring definition of that until the SubClass
is initialized.
This behavior is documented on the Kotlin website under "Derived class initialization order":
During construction of a new instance of a derived class, the base class initialization is done as the first step (preceded only by evaluation of the arguments for the base class constructor) and thus happens before the initialization logic of the derived class is run.
...
It means that, by the time of the base class constructor execution, the properties declared or overridden in the derived class are not yet initialized. If any of those properties are used in the base class initialization logic (either directly or indirectly, through another overridden open member implementation), it may lead to incorrect behavior or a runtime failure. Designing a base class, you should therefore avoid using open members in the constructors, property initializers, and init blocks. [emphasis mine]
FWIW, this is similar to the reason that some Java code analysis tools will complain if you refer to non-final methods in a constructor. The way around this in Kotlin is to not refer to open
properties in your init
blocks in the superclass.