Eu criei a seguinte hierarquia de classes:
open class A {
init {
f()
}
open fun f() {
println("In A f")
}
}
class B : A() {
var x: Int = 33
init {
println("x: " + x)
}
override fun f() {
x = 1
println("x in f: "+ x)
}
init {
println("x2: " + x)
}
}
fun main() {
println("Hello World!!")
val b = B()
println("in main x : " + b.x)
}
A saída deste código é
Hello World!!
x in f: 1
x: 33
x2: 33
in main x : 33
Mas se eu mudar a inicialização x
do
var x: Int = 33
para
var x: Int = 0
a saída mostra a invocação do método em contraste com a saída acima:
Hello World!!
x in f: 1
x: 1
x2: 1
in main x : 1
Alguém sabe por que a inicialização com 0
causa um comportamento diferente daquele com outro valor?
class
kotlin
initialization
polymorphism
overriding
PRATYUSH SINGH
fonte
fonte
Respostas:
superclasse é inicializada antes da subclasse.
A chamada do construtor de B chama o construtor de A, que chama a função f imprimindo "x em f: 1", depois que A é inicializado, o restante de B é inicializado.
Então, essencialmente, a configuração do valor está sendo substituída.
(Quando você inicializa as primitivas com seu valor zero no Kotlin, elas tecnicamente simplesmente não são inicializadas)
Você pode observar esse comportamento de "substituição" alterando a assinatura de
var x: Int = 0
paravar x: Int? = 0
Como
x
não é mais a primitivaint
, o campo é realmente inicializado com um valor, produzindo a saída:fonte
Esse comportamento é descrito na documentação - https://kotlinlang.org/docs/reference/classes.html#derived-class-initialization-order
UPD:
Há um erro que produz essa inconsistência - https://youtrack.jetbrains.com/issue/KT-15642
fonte
f()
noinit
bloco deA
dá o aviso "Chamando a função não final f no construtor"var x: Int = 0
) da classe derivada não é executada, o que é contrário ao que a documentação diz, o que me leva a acreditar que isso pode ser um bug.