Saya telah membuat hierarki kelas berikut:
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)
}
Output dari kode ini adalah
Hello World!!
x in f: 1
x: 33
x2: 33
in main x : 33
Tetapi jika saya mengubah inisialisasi x
dari
var x: Int = 33
untuk
var x: Int = 0
output menunjukkan permohonan metode berbeda dengan output di atas:
Hello World!!
x in f: 1
x: 1
x2: 1
in main x : 1
Adakah yang tahu mengapa inisialisasi dengan 0
menyebabkan perilaku yang berbeda dari yang dengan nilai lain?
class
kotlin
initialization
polymorphism
overriding
PRATYUSH SINGH
sumber
sumber
Jawaban:
kelas super diinisialisasi sebelum sub kelas.
Panggilan konstruktor B memanggil konstruktor A, yang memanggil fungsi f mencetak "x dalam f: 1", setelah A diinisialisasi, sisa B diinisialisasi.
Jadi pada dasarnya, pengaturan nilai sedang ditimpa.
(Ketika Anda menginisialisasi primitif dengan nilai nol di Kotlin, secara teknis mereka tidak menginisialisasi sama sekali)
Anda dapat mengamati perilaku "menimpa" ini dengan mengubah tanda tangan dari
var x: Int = 0
untukvar x: Int? = 0
Karena
x
bukan lagi primitifint
, bidang sebenarnya diinisialisasi ke nilai, menghasilkan output:sumber
Perilaku ini dijelaskan dalam dokumentasi - https://kotlinlang.org/docs/reference/classes.html#derived-class-initialization-order
UPD:
Ada bug yang menghasilkan inkonsistensi ini - https://youtrack.jetbrains.com/issue/KT-15642
sumber
f()
diinit
blokA
memberi peringatan "Memanggil fungsi non-final f dalam konstruktor"var x: Int = 0
) dari kelas turunan tidak berjalan sama sekali yang bertentangan dengan apa yang dikatakan dokumentasi yang membuat saya percaya bahwa ini mungkin bug.