ProgrammazioneSviluppatore Backend

Spiega le differenze tra le classi dei dati (data classes), le classi normali e le classi con ereditarietà in Kotlin. In quali casi è necessario utilizzare una data class e quali restrizioni impone il compilatore?

Supera i colloqui con l'assistente IA Hintsage

Risposta

In Kotlin, la data class è destinata a memorizzare dati. Il compilatore genera automaticamente per esse i metodi equals(), hashCode(), toString(), oltre alle funzioni copy() e componentN(), che facilitano notevolmente il lavoro con tali oggetti:

data class User(val name: String, val age: Int) val u1 = User("Ivan", 30) val u2 = u1.copy(age = 31)

Le classi normali non hanno metodi auto-generati; tutto deve essere scritto manualmente. È meglio utilizzare una data class per DTO, modelli e strutture dati.

Restrizioni della data class:

  • Il costruttore primario deve contenere almeno un parametro.
  • Tutti i parametri del costruttore devono essere contrassegnati come val o var.
  • La data class non può essere abstract, open, sealed o inner.
  • Non è consigliabile utilizzare la data class per classi con logica di business o gerarchie di ereditarietà.

Domanda trabocchetto

"È possibile dichiarare una data class con ereditarietà da un'altra data class? Perché (o perché no)?"

No, non è possibile ereditare direttamente una data class da un'altra. La data class può ereditare solo da un'interfaccia o da una classe normale (non data class). Questo è stato fatto per prevenire confusione con i metodi auto-generati (ad esempio, copiare proprietà ereditate non è evidente).

data class Base(val id: Int) data class Child(val name: String) : Base(1) // Errore di compilazione: non consentito

Esempi di errori reali dovuti alla mancanza di conoscenza delle sottigliezze dell'argomento


Storia

In un progetto bancario sono state utilizzate data class con logica di business e ereditarietà. Dopo aver aggiunto un nuovo campo, è diventato impossibile copiare correttamente gli oggetti, parte della logica di business è andata persa (metodi non ereditati), causando errori nei calcoli delle commissioni.


Storia

In una piattaforma e-commerce, la data class è stata utilizzata per memorizzare lo stato del carrello dell'utente. Dopo aver aggiornato lo stato tramite copy(), si è dimenticato che le liste interne non vengono copiate in profondità. Ciò ha causato "fughe" di dati tra le sessioni degli utenti.


Storia

In un progetto con integrazione di API esterne, la serializzazione della data class in JSON portava alla comparsa di campi con visibilità privata, violando il contratto API e causando errori lato client.