Storia della domanda:
Le interfacce con il modificatore sealed sono state introdotte in Kotlin come un'evoluzione del concetto di sealed class. Fino a Kotlin 1.5, solo le sealed class consentivano di limitare il set di possibili eredi, il che è particolarmente importante per lavorare in modo sicuro con gerarchie di stati (macchine a stati, DSL, ecc.). Introdurre le interfacce sealed ha fornito la possibilità di limitare in modo simile le implementazioni delle interfacce, senza legarsi alle classi.
Problema:
Un'interfaccia aperta può essere implementata ovunque nel programma, il che può portare a una crescita incontrollata del numero di implementazioni e complicare la manutenzione del codice. Quando si elabora tramite un'espressione when, il compilatore non può avvisare su rami non considerati.
Soluzione:
Sealed interface limita le implementazioni solo a quelle definite in un modulo (o nello stesso file, se l'interfaccia non è top-level). Questo tipo di controllo è applicato a strutture simili a enum sicure, al pattern ADT e ai gestori di stato. Il compilatore conosce tutte le implementazioni e aiuta nell'analisi del codice.
Esempio di codice:
sealed interface NetworkResult class Success(val data: String): NetworkResult class Error(val cause: Throwable): NetworkResult object Loading: NetworkResult fun handleResult(result: NetworkResult): String = when (result) { is Success -> "Success with ${result.data}" is Error -> "Error: ${result.cause.message}" Loading -> "Loading..." }
Caratteristiche chiave:
È possibile implementare un'interfaccia sealed al di fuori del file corrente?
Risposta: A differenza della sealed class, le interfacce sealed possono essere implementate in altri file, ma solo all'interno del modulo corrente (o dell'unità di compilazione, se l'interfaccia non è top-level).
Le interfacce sealed possono avere metodi aperti con implementazione predefinita?
Sì, come le normali interfacce, un'interfaccia sealed può contenere implementazioni di default delle funzioni.
sealed interface Mode { fun description(): String = "Unknown mode" }
È possibile serializzare un'interfaccia sealed utilizzando i serializzatori standard (ad esempio, kotlinx.serialization)?
Sì, ma sarà necessario specificare esplicitamente tutte le implementazioni. Nel Kotlinx.serialization, il supporto per le interfacce sealed non è apparso immediatamente, è importante specificare esplicitamente i tipi serializzabili.
Nel progetto, è stata descritta un'interfaccia sealed per tutti i tipi di stati UI, ma le implementazioni hanno iniziato a comparire in diverse parti dell'applicazione. Poi è stato aggiunto un nuovo tipo di stato, dimenticando di aggiornare il blocco di elaborazione, il che ha portato all'ignoranza del nuovo stato nei log.
Pro:
Contro:
È stata utilizzata un'interfaccia sealed per tutte le risposte di rete. Grazie a ciò, all'aggiunta di un nuovo tipo di risposta, l'IDE ha subito evidenziato tutti i luoghi in cui l'elaborazione viene gestita tramite when. L'errore viene corretto immediatamente, senza buchi inaspettati nella logica.
Pro:
Contro: