In questo articolo imparerai a conoscere le classi Sealed, come vengono create e quando usarle con l'aiuto di esempi.
Le classi sigillate vengono utilizzate quando un valore può avere solo uno dei tipi di un insieme limitato (gerarchie limitate).
Prima di entrare nei dettagli sulle classi sigillate, esploriamo quale problema risolvono. Facciamo un esempio (tratto dal sito web ufficiale di Kotlin - articolo sulle classi Sealed):
class Expr class Const(val value: Int) : Expr class Sum(val left: Expr, val right: Expr) : Expr fun eval(e: Expr): Int = when (e) ( is Const -> e.value is Sum -> eval(e.right) + eval(e.left) else -> throw IllegalArgumentException("Unknown expression") )
Nel programma precedente, la classe base Expr ha due classi derivate Const (rappresenta un numero) e Sum (rappresenta la somma di due espressioni). Qui è obbligatorio utilizzare else
branch per la condizione predefinita nell'espressione when.
Ora, se si ricava una nuova sottoclasse dalla Expr
classe, il compilatore non rileverà nulla mentre else
branch la gestisce, il che può portare a bug. Sarebbe stato meglio se il compilatore avesse emesso un errore quando abbiamo aggiunto una nuova sottoclasse.
Per risolvere questo problema, puoi utilizzare la classe sealed. Come accennato, la classe sealed limita la possibilità di creare sottoclassi. E, quando gestisci tutte le sottoclassi di una classe sealed in when
un'espressione, non è necessario utilizzare else
branch.
Per creare una classe sigillata, viene utilizzato il modificatore sigillato. Per esempio,
classe sigillata Espr
Esempio: classe sigillata
Ecco come puoi risolvere il problema precedente usando la classe sealed:
sealed class Expr class Const(val value: Int) : Expr() class Sum(val left: Expr, val right: Expr) : Expr() object NotANumber : Expr() fun eval(e: Expr): Int = when (e) ( is Const -> e.value is Sum -> eval(e.right) + eval(e.left) NotANumber -> java.lang.Double.NaN )
Come puoi vedere, non ci sono else
rami. Se si ricava una nuova sottoclasse dalla Expr
classe, il compilatore si lamenterà a meno che la sottoclasse non venga gestita when
nell'espressione.
Poche note importanti
- Tutte le sottoclassi di una classe sealed devono essere dichiarate nello stesso file in cui viene dichiarata la classe sealed.
- Una classe sealed è astratta di per sé e non è possibile istanziare oggetti da essa.
- Non è possibile creare costruttori non privati di una classe sealed; i loro costruttori sono
private
per impostazione predefinita.
Differenza tra Enum e Sealed Class
La classe Enum e la classe sealed sono piuttosto simili. Anche l'insieme di valori per un tipo enum è limitato come una classe sealed.
L'unica differenza è che enum può avere solo una singola istanza, mentre una sottoclasse di una classe sealed può avere più istanze.