Init blokları ve Kotlin'deki super çağrısı, nesnelerin doğru bir şekilde başlatılmasını sağlamak için sınıf hiyerarşisini dikkate alır. Bu, yapılar ve kalıtım üzerindeki temel mekanizmalardır.
Java'da yapıcılar, super(...) ile açıkça veya varsayılan olarak dolaylı yoldan çağrılabilir. Kotlin'de durum tamamen farklıdır: birincil ve ikincil yapıcılar arasında kesin bir ayrım vardır ve init bloğu, başlatma için kullanılır.
Ana zorluk, özelliklerin ne zaman başlatıldığını, init bloklarının ne zaman çağrıldığını ve özellikle sınıfların kalıtımı ve birincil/ikincil yapıcıların kombinasyonu söz konusu olduğunda yapıcı çağrı sırasının nasıl kurulduğunu doğru bir şekilde anlamaktır.
Kod örneği:
open class Base(val name: String) { init { println("Base init: $name") } } class Derived(name: String, val age: Int): Base(name) { init { println("Derived init: $name, $age") } } fun main() { Derived("Ivan", 25) } // Çıktı: // Base init: Ivan // Derived init: Ivan, 25
Anahtar özellikler:
Kalıtım zincirinde init blokları hangi sırayla çalıştırılır?
Öncelikle süper sınıfın init blokları, onun özelliklerinin başlatılmasının ardından çalıştırılır, ardından alt sınıfın init blokları, kendi özelliklerinden sonra çalışır.
Kod örneği:
open class A { init { println("A") } } class B: A() { init { println("B") } } fun main() { B() } // A -> B
Kotlin'de super() yapıcı dışında çağrılabilir mi?
Hayır, süper sınıf çağrısı yalnızca yapıcı tanımının bir parçası olarak yapılır ve süper yapıcıya parametre sağlar.
Kotlin'de ikincil yapıcı, birincil yapıcıyı çağırmaktan kaçınabilir mi?
Hayır, tüm ikincil yapıcılar ya başka bir ikincil yapıcıya ya da birincil yapıcıya delegasyon yapmak zorundadır. Birincil yapıcı, süper yapıcıyı da çağırmaktadır.
Geliştirici, süper sınıfın init blokunda alt sınıfta başlatılan bir özelliğe erişmeye çalışıyor:
open class A { init { println(f()) } open fun f() = "A" } class B : A() { private val s = "B" override fun f() = s }``` **Artılar:** - Polimorfizm kullanımı. **Eksikler:** - Özellik s henüz başlatılmamış, süper sınıfın init çağrısı sırasında - sonuç null veya hata. ## Pozitif Durum Başlatmayı, yapıcıdan yeniden tanımlanabilir yöntemler veya özellikleri çağırmamayı sağlayacak şekilde organize etme: ```kotlin open class A { init { println("init A") } open fun f() = "A" } class B : A() { private val s = "B" override fun f() = s init { println(f()) } }``` **Artılar:** - Başlatılmamış verilere yönlendirme yok; - Başlatma sırası garanti altına alınmıştır. **Eksikler:** - Doğru başlatma için kod miktarı artmaktadır.