ProgrammatieKotlin/Java ontwikkelaar

Hoe werkt de constructorovererving in Kotlin, hoe werkt de aanroep van de superconstructor en welke valkuilen zijn er bij het combineren van primary en secondary constructors? Geef voorbeelden van verschillende gevallen en leg het verschil met Java uit.

Slaag voor sollicitatiegesprekken met de Hintsage AI-assistent

Antwoord

In Kotlin kan een klasse één primary constructor en een onbeperkt aantal secondary constructors hebben. Het verschil met Java is dat de primary constructor in de header van de klasse wordt gedeclareerd en parameters en modifiers kan bevatten. Secondary constructors moeten altijd een andere secondary constructor, de primary constructor of de constructor van de superklasse aanroepen (met behulp van het sleutelwoord super).

Belangrijke kenmerken:

  • Als de superklasse een primary constructor heeft met verplichte parameters, moet de afgeleide klasse deze altijd expliciet aanroepen via : super(...).
  • In de secondary constructor wordt de basis klasse aangeroepen met super(...) of een andere secondary/primary constructor.
  • Er is geen conflictoplossing bij initialisatie toegestaan: alle velden moeten altijd correct zijn geïnitialiseerd.

Voorbeeld van gebruik met overerving:

open class A(val a: Int) { constructor(a: Int, str: String) : this(a) { println("Secondary in A: $str") } } class B : A { constructor(a: Int) : super(a) { println("Secondary in B") } constructor(a: Int, s: String) : super(a, s) { println("Secondary #2 in B") } }

Wat is het verschil met de benadering in Java:

  • In Kotlin is het niet mogelijk om de constructor van de superklasse NIET aan te roepen.
  • De primary constructor initialiseert altijd de basisparameters en kan impliciet zijn.

Vraag met een valstrik

Is het mogelijk om in Kotlin een afgeleide klasse te creëren zonder expliciet de constructor van de superklasse aan te roepen, als er alleen een bepaalde constructor in de basis klasse is?

Antwoord: Nee, in tegenstelling tot Java is de aanroep van de superconstructor in Kotlin verplicht en moet deze expliciet worden aangegeven, hetzij in "het hoofd" van de klasse, hetzij na het sleutelwoord : super().

Voorbeeld van een fout:

open class Base(val x: Int) class Derived : Base // Compilatiefout!

Voorbeelden van echte fouten door onbekendheid met de nuances van het onderwerp


Verhaal

In een microservices project na de migratie naar Kotlin werd de expliciete verwijzing naar de ouderconstructor vergeten: de constructor van de superklasse met een verplichte parameter werd niet aangeroepen, de service compileerde niet, en het was nodig om de handtekeningen te refactoren.


Verhaal

Het Android-project had een diepe hiërarchie (Activity → BaseActivity → CustomActivity), het toevoegen van een secondary constructor verloor parameters, waardoor de verkeerde basisconstructor werd aangeroepen en delen van velden null bleven — de applicatie viel op runtime met NPE.


Verhaal

In open-source bibliotheekcode omzeilde de secondary constructor in de afgeleide klasse per ongeluk de primary constructor, wat leidde tot twee verschillende initialisatiepaden: soms werd het veld geïnitialiseerd, soms niet. De fout werd pas na veel tijd gevonden door complexe bugrapporten.