Sobes.tech
Middle

Jakie są cechy pracy z konstruktorami i inicjalizacją obiektów w Kotlin?

sobes.tech AI

Odpowiedź od AI

W Kotlinie klasy mogą mieć konstruktor główny i jeden lub więcej konstruktorów pomocniczych.

Konstruktor główny:

  • Deklarowany w nagłówku klasy:
    class User(val name: String, var age: Int = 0) {
        // ciało klasy
    }
    
  • Nie ma ciała. Kod inicjalizacji jest wykonywany w blokach init.
  • Właściwości zadeklarowane w konstruktorze głównym za pomocą val lub var stają się właściwościami klasy.
  • Parametry konstruktora można używać w blokach init i podczas inicjalizacji właściwości:
    init {
        println("Inicjalizacja użytkownika $name")
    }
    
    val description = "Użytkownik: $name, wiek: $age"
    
  • Jeśli konstruktor główny nie ma adnotacji ani modyfikatorów widoczności, słowo kluczowe constructor można pominąć.

Bloki init:

  • Zawierają kod inicjalizacji, który jest wykonywany podczas tworzenia instancji klasy.
  • Wykonują się w kolejności, w jakiej są zadeklarowane.
  • Wykonują się po wywołaniu konstruktora głównego (jeśli istnieje), ale przed konstruktorami pomocniczymi.

Konstruktory pomocnicze:

  • Deklarowane słowem kluczowym constructor.
  • Mogą delegować wywołanie do innego konstruktora tej samej klasy za pomocą this() lub do konstruktora klasy bazowej za pomocą super(). Wywołanie delegacji musi być pierwszą instrukcją.
    class User(val name: String) {
        constructor(name: String, age: Int) : this(name) {
            println("Konstruktor pomocniczy")
            // dodatkowa logika inicjalizacji
        }
    }
    
  • Jeśli klasa ma konstruktor główny, wszystkie konstruktory pomocnicze muszą jawnie lub niejawnie delegować do niego za pomocą this().

Kolejność inicjalizacji:

  1. Wykonanie kodu konstruktora głównego (jeśli istnieje).
  2. Wykonanie bloków init w kolejności ich deklaracji.
  3. Wykonanie kodu konstruktora pomocniczego (jeśli jest używany).

Przykład:

class Example(name: String) {
    init {
        println("Pierwszy blok init dla $name")
    }

    val property1 = "Właściwość 1"

    init {
        println("Drugi blok init dla $name")
    }

    constructor(name: String, age: Int) : this(name) {
        println("Konstruktor pomocniczy dla $name, wiek $age")
    }
}

fun main() {
    val ex1 = Example("Użytkownik1") // Wypisze: Pierwszy blok init dla Użytkownik1, Drugi blok init dla Użytkownik1
    val ex2 = Example("Użytkownik2", 30) // Wypisze: Pierwszy blok init dla Użytkownik2, Drugi blok init dla Użytkownik2, Konstruktor pomocniczy dla Użytkownik2, wiek 30
}

Kluczowe cechy: deklaratyjna składnia konstruktorów głównych, użycie bloków init do logiki inicjalizacji, jawna delegacja w konstruktorach pomocniczych zapewniająca spójność tworzenia obiektów.