Opowiedz o inicjalizatorach w klasach w języku Kotlin.
sobes.tech AI
Odpowiedź od AI
W Kotlinie klasy mogą mieć konstruktor główny i jeden lub więcej konstruktorów pomocniczych. Inicjalizatory to bloki kodu init, które są wykonywane w kolejności po ich deklaracji, po konstruktorze głównym (jeśli istnieje) lub po konstruktorze pomocniczym, jeśli konstruktor główny nie istnieje.
Konstruktor główny
Jest deklarowany bezpośrednio w nagłówku klasy. Może zawierać parametry używane do inicjalizacji właściwości.
class User(name: String, age: Int) {
init {
// Ten blok jest wykonywany podczas tworzenia instancji klasy
println("Użytkownik utworzony: $name, $age")
}
}
Konstruktor pomocniczy
Jest deklarowany słowem kluczowym constructor i zawsze musi delegować wywołanie do innego konstruktora tej samej klasy, albo do konstruktor głównego (przez this), albo do innego pomocniczego.
class User {
init {
// Ten blok jest wykonywany jako pierwszy, jeśli istnieje konstruktor główny
}
constructor(name: String) : this() {
// Konstruktor pomocniczy 1
println("Użytkownik utworzony z nazwą: $name")
}
constructor(name: String, age: Int) : this(name) {
// Konstruktor pomocniczy 2, wywołuje pierwszy pomocniczy
println("Użytkownik utworzony z nazwą i wiekiem: $name, $age")
}
}
Kolejność wykonywania
- Kod w konstruktorze głównym (jeśli ma parametry, są używane).
- Bloki
initw kolejności. - Kod w wywołanym konstruktorze pomocniczym (po delegacji).
Przykład kolejności wykonywania:
class Example {
init {
println("Blok init 1")
}
constructor(i: Int) {
println("Konstruktor pomocniczy $i")
}
init {
println("Blok init 2")
}
}
fun main() {
Example(10)
}
Wynik:
Blok init 1
Blok init 2
Konstruktor pomocniczy 10
Nawet jeśli wywołuje się konstruktor pomocniczy, bloki init zawsze są wykonywane przed jego ciałem. Zapewnia to, że główna inicjalizacja obiektu jest zakończona przed wykonaniem specyficznego kodu konstruktor pomocniczego.
Inicjalizatory są nieodzowne do wykonywania logiki, która musi być wykonana podczas tworzenia dowolnej instancji klasy, niezależnie od używanego konstruktora. Na przykład, do sprawdzania danych wejściowych lub konfigurowania stanu obiektu.