Ich habe die folgende Klassenhierarchie erstellt:
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)
}
Die Ausgabe dieses Codes ist
Hello World!!
x in f: 1
x: 33
x2: 33
in main x : 33
Aber wenn ich die Initialisierung von x
von ändere
var x: Int = 33
zu
var x: Int = 0
Die Ausgabe zeigt den Aufruf der Methode im Gegensatz zur obigen Ausgabe:
Hello World!!
x in f: 1
x: 1
x2: 1
in main x : 1
Weiß jemand, warum die Initialisierung mit 0
ein anderes Verhalten verursacht als die mit einem anderen Wert?
class
kotlin
initialization
polymorphism
overriding
PRATYUSH SINGH
quelle
quelle
Antworten:
Die Superklasse wird vor der Unterklasse initialisiert.
Der Konstruktoraufruf von B ruft den Konstruktor von A auf, der die Funktion f aufruft, die "x in f: 1" druckt, nachdem A initialisiert wurde, wird der Rest von B initialisiert.
Im Wesentlichen wird die Einstellung des Werts überschrieben.
(Wenn Sie Grundelemente mit ihrem Nullwert in Kotlin initialisieren, werden sie technisch überhaupt nicht initialisiert.)
Sie können dieses "Überschreiben" -Verhalten beobachten, indem Sie die Signatur von ändern
var x: Int = 0
zuvar x: Int? = 0
Da
x
es nicht mehr das Grundelement istint
, wird das Feld tatsächlich auf einen Wert initialisiert, wodurch die Ausgabe erzeugt wird:quelle
Dieses Verhalten wird in der Dokumentation beschrieben - https://kotlinlang.org/docs/reference/classes.html#derived-class-initialization-order
UPD:
Es gibt einen Fehler, der diese Inkonsistenz verursacht - https://youtrack.jetbrains.com/issue/KT-15642
quelle
f()
desinit
Blocks vonA
gibt die Warnung "Aufrufen der nicht endgültigen Funktion f im Konstruktor"var x: Int = 0
) der abgeleiteten Klasse jedoch überhaupt nicht ausgeführt, was im Widerspruch zu den Angaben in der Dokumentation steht, was mich zu der Annahme veranlasst, dass dies ein Fehler sein könnte.