ProgrammazioneSviluppatore Kotlin

Spiega le sottigliezze della visibilità e dell'ereditarietà dei costruttori in Kotlin: quali sono le differenze tra il costruttore primario e i costruttori secondari, le sfumature con l'ereditarietà e i modificatori di visibilità. Porta esempi di codice e errori tipici.

Supera i colloqui con l'assistente IA Hintsage

Risposta.

In Kotlin, ogni classe può avere un costruttore primario (specificato nell'intestazione della classe) e diversi costruttori secondari (tramite constructor).

  • Il costruttore primario non può contenere codice al di fuori della dichiarazione (la logica si trova in init).
  • I costruttori secondari implementano ulteriori varianti di inizializzazione.
  • Se il genitore non ha un costruttore senza parametri, il discendente è obbligato a chiamare esplicitamente il suo costruttore.
  • Con i modificatori (private, protected, internal, public) è possibile nascondere o limitare la visibilità dei costruttori.

Esempio con costruttori primari e secondari:

open class Person(val name: String) { constructor(name: String, age: Int) : this(name) { // costruttore secondario } } class Employee : Person { constructor(name: String) : super(name) // È necessario chiamare esplicitamente super }

Modificatori di visibilità:

class Secret private constructor() { companion object { fun create() = Secret() } } val s = Secret.create() // Ok, mentre Secret() - errore

Sfumature:

  • Se una classe con un costruttore primario ha parametri, non è possibile ereditare senza passare questi parametri.
  • I costruttori secondari devono chiamare indirettamente o direttamente il primario.
  • Le classi annidate non hanno accesso al costruttore privato della classe esterna.

Domanda trabocchetto.

È possibile ereditare una classe in Kotlin e non chiamare il suo costruttore primario?

Risposta: No. In Kotlin, durante l'ereditarietà, deve sempre essere chiamato almeno un costruttore del genitore — sia il primario che il secondario (tramite super()).

Esempio:

open class A(val x: Int) class B: A // Errore: è necessario chiamare esplicitamente il costruttore A

Esempi di errori reali dovuti alla disconoscenza delle sottigliezze dell'argomento.


Storia

Nel team hanno cercato di vietare la creazione diretta di oggetti della classe e hanno reso il costruttore privato. Tuttavia, hanno dimenticato di implementare il metodo factory. Ciò ha portato all'impossibilità di testare la classe senza riflessione e al bloqueo del CI.


Storia

Hanno ereditato una classe con parametri obbligatori nel costruttore primario, ma non li hanno passati durante la dichiarazione dell'ereditarietà. Questo è stato scoperto solo durante la fase di compilazione dopo una lunga fase di debug.


Storia

Durante l'uso dei costruttori secondari, hanno dimenticato che tutti devono chiamare il primario. Di conseguenza, gli oggetti sono stati inizializzati senza i parametri necessari, il che ha portato a un NullPointerException durante il runtime.