English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
In diesem Artikel werden Sie mit Hilfe von Beispielen geschlossene (geschlossene) Klassen kennenlernen, wie man sie erstellt und wann man sie verwendet.
Wenn ein Wert nur aus einer beschränkten Menge (einer beschränkten Hierarchie) eines Typs enthalten kann, werden geschlossene Klassen verwendet.
Bevor wir detailliert geschlossene Klassen beschreiben, lassen Sie uns die Probleme besprechen, die sie lösen. Lassen Sie uns ein Beispiel nennen:
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("Unbekannter Ausdruck") }
Im obigen Programm hat die Basisklasse Expr zwei Ableitungen Const (stellt eine Zahl dar) und Sum (stellt die Summe zweier Ausdrücke dar). Hier muss eine else-Branche verwendet werden, um in der when-AusdrucksbedingungStandardbedingung.
Jetzt, wenn Sie eine neue Unterklasse von der Klasse Expr ableiten, wird der Compiler nichts erkennen, weil die else-Branche sie behandelt, was zu Fehlern führen kann. Es ist besser, wenn der Compiler Fehler auslöst, wenn Sie neue Unterklassen hinzufügen.
Um dieses Problem zu lösen, können Sie geschlossene Klassen verwenden. Wie bereits erwähnt, beschränken geschlossene Klassen die Möglichkeit, Unterklassen zu erstellen. Und wenn Sie alle Unterklassen von geschlossenen Klassen in einer when-Ausdrucksbedingung verarbeiten, müssen Sie keine else-Branche verwenden.
Um geschlossene Klassen zu erstellen, verwenden Sie den geschlossenen Modifikator sealed. Zum Beispiel:
sealed class Expr
Dies ist die Methode zur Lösung des obigen Problems mit geschlossenen Klassen:
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 }
Wie du siehst, gibt es keine else-Branche. Wenn du eine neue Unterklasse von der Klasse Expr ableitest, wird der Compiler einen Fehler melden, es sei denn, die Unterklasse wird im when-Ausdruck behandelt.
Alle Unterklasse der versiegelten Klasse müssen in derselben Datei wie die versiegelte Klasse deklariert werden.
Die versiegelte Klasse selbst istAbstraktSie können keine Objekte davon instanziieren.
Man kann keine nicht-privaten Konstruktoren für versiegelte Klassen erstellen; ihre Konstruktoren sind standardmäßig private.
EnumerationsklasseSehr ähnlich wie versiegelte Klassen. Der Wertesatz eines Enumerationstyps ist ebenfalls wie bei versiegelten Klassen begrenzt.
Der einzige Unterschied ist, dass Enumeration nur eine Instanz haben kann, während die Unterklasse einer versiegelten Klasse mehrere Instanzen haben kann.