ProgrammazioneSviluppatore Android/Kotlin

Che cosa sono le interfacce sealed in Kotlin, come e perché usarle?

Supera i colloqui con l'assistente IA Hintsage

Risposta.

Interfaccia sealed — è un tipo speciale di interfaccia in Kotlin che consente di limitare il numero delle sue implementazioni all'interno di un modulo. Le classi sealed sono apparse per la prima volta in Kotlin in precedenza, mentre le interfacce sealed sono state aggiunte a partire da Kotlin 1.5 come evoluzione per un maggiore controllo sui tipi partecipanti, ad esempio, nelle gerarchie di stati o nella gestione degli eventi.

Storia della questione

In precedenza, gli sviluppatori utilizzavano classi sealed per limitare l'ereditarietà e creare gerarchie sicure. Tuttavia, per flessibilità e supporto di strutture in cui l'ereditarietà da più tipi è utile, sono state necessarie le interfacce sealed.

Problema

Senza le interfacce sealed, non è possibile gestire in modo flessibile l'insieme delle sottoclassi dell'interfaccia. Questo rende impossibile, ad esempio, un controllo esaustivo with quando si gestiscono stati, se tutto è costruito su interfacce e non solo su classi astratte/concrete.

Soluzione

L'uso di interfaccia sealed consente di:

  • Descrivere un insieme fisso di implementazioni.
  • Garantire che tutte le implementazioni siano note al compilatore.
  • Utilizzare in sicurezza il when senza il ramo else — il compilatore segnalerà i casi non coperti.

Esempio di codice:

sealed interface Event class Click : Event class Scroll : Event fun handle(event: Event) = when(event) { is Click -> println("Evento Click") is Scroll -> println("Evento Scroll") }

Caratteristiche chiave:

  • Restrizione e controllo dell'insieme delle implementazioni ammesse.
  • Possibilità di ereditare da più interfacce sealed contemporaneamente.
  • Sicurezza durante il pattern matching (when).

Domande ingannevoli.

Le interfacce sealed possono avere implementazioni al di fuori del file in cui sono dichiarate?

No, le implementazioni di un'interfaccia sealed devono trovarsi nello stesso modulo. Questo garantisce completezza e consente al compilatore di controllare il loro numero.

Come interagiscono le interfacce sealed con classi e oggetti?

Un'interfaccia sealed può essere implementata sia da classi normali che da oggetti, oltre che da data object (Kotlin 1.9+). Tale interfaccia può essere presente nell'ereditarietà multipla, cosa che non è possibile con una classe sealed.

sealed interface Operation object Add: Operation object Subtract: Operation

Le interfacce sealed possono essere annidate?

Sì, è possibile dichiarare un'interfaccia sealed sia all'interno di una classe sealed che sopra altre interfacce. L'importante è che tutte le implementazioni si trovino all'interno dello stesso modulo.

Errori tipici e anti-pattern

  • Definire implementazioni di un'interfaccia sealed in moduli diversi porta a errori di compilazione.
  • Tentare di utilizzare un'interfaccia sealed con l'idea che funzioni come una classe sealed, mentre l'interfaccia sealed può essere ereditata da altre interfacce.

Esempio dalla vita reale

Caso negativo

Nell'applicazione, gli stati UI sono stati descritti semplicemente come interfacce senza modificatore sealed. È stata dimenticata un'implementazione, e l'analisi statica non l'ha catturata; l'errore è emerso solo in produzione.

Pro:

  • Pattern familiare di interfacce Java.

Contro:

  • Nessuna garanzia di completezza in when.
  • Vulnerabilità all'emergere di implementazioni "esterne".

Caso positivo

Utilizzo di un'interfaccia sealed per il modello di eventi dello schermo. Tutte le implementazioni si trovano all'interno dello stesso file del modulo, il compilatore avvisa in caso di rami non chiusi quando viene dimenticato un caso in when.

Pro:

  • Completamente type-safety.
  • Comodità di supporto ed estensione.

Contro:

  • Utilizzabile solo entro un modulo.