Kotlin Sealed Class – Tutorial
In diesem Tutorial werden wir uns mit Kotlin Sealed Class beschäftigen. Was sind sie? Wozu dienen sie? All diese Fragen werden wir hier beantworten.
Kotlin Sealed Class
Um es einfach auszudrücken, wie der Name schon sagt, sind Sealed Classes versiegelt oder geschlossen, was sie eingeschränkt macht. Sealed Classes werden verwendet, um eingeschränkte Klassenhierarchien darzustellen, bei denen das Objekt oder der Wert nur einen der Typen annehmen kann, wodurch Ihre Typhierarchien festgelegt werden. Sealed Classes werden häufig in Fällen verwendet, in denen bekannt ist, dass ein gegebener Wert nur unter einer gegebenen Menge von Optionen liegen kann.
Implementierung von Kotlin Sealed Classes
Sealed Classes in Kotlin werden auf folgende Weise implementiert.
sealed class A{
class B : A()
class C : A()
}
Um eine Sealed Class zu spezifizieren, müssen Sie den Modifier sealed hinzufügen. Eine Sealed Class kann nicht instanziiert werden. Daher sind sie implizit abstrakt. Folgendes funktioniert NICHT.
fun main(args: Array<String>)
{
var a = A() //compiler error. Class A cannot be instantiated.
}
Konstruktoren einer Sealed Class sind standardmäßig privat. Alle Unterklassen einer Sealed Class müssen innerhalb derselben Datei deklariert werden. Sealed Classes sind wichtig, um die Typsicherheit zu gewährleisten, indem sie die Menge der Typen bereits zur Compile-Zeit einschränken.
sealed class A{
class B : A()
{
class E : A() //this works.
}
class C : A()
init {
println("sealed class A")
}
}
class D : A() //this works
{
class F: A() //This won't work. Since sealed class is defined in another scope.
}
Erstellung einer Sealed Class mit Konstruktoren.
sealed class A(var name: String){
class B : A("B")
class C : A("C")
}
class D : A("D")
fun main(args: Array<String>) {
var b = A.B()
var d = D()
}
Hinzufügen von Data Class und Object in einer Sealed Class.
fun main(args: Array<String>) {
val e = A.E("Anupam")
println(e) //prints E(name=Anupam)
var d = A.D
d.name() //prints Object D
}
sealed class A{
class B : A()
class C : A()
object D : A()
{
fun name()
{
println("Object D")
}
}
data class E(var name: String) : A()
}
Unterschied zwischen Enum und Sealed Classes
In Kotlin können Sealed Classes als Enum-Klassen auf Steroiden bezeichnet werden. Sealed Classes ermöglichen es uns, Instanzen mit unterschiedlichen Typen zu erstellen, im Gegensatz zu Enums, die uns einschränken, denselben Typ für alle Enum-Konstanten zu verwenden. Folgendes ist in Enum-Klassen nicht möglich.
enum class Months(string: String){
January("Jan"), February(2),
}
Enum-Klassen erlauben nur einen einzigen Typ für alle Konstanten. Hier kommen Sealed Classes zu unserer Rettung, indem sie mehrere Instanzen erlauben.
sealed class Months {
class January(var shortHand: String) : Months()
class February(var number: Int) : Months()
class March(var shortHand: String, var number: Int) : Months()
}
Wie können Sie dieses Feature von Sealed Classes in Ihren Projekten nutzen?
In einer Anwendung ähnlich einem Newsfeed können Sie drei verschiedene Klassentypen für Status-, Bild- und Videoposts erstellen, wie unten gezeigt.
sealed class Post
{
class Status(var text: String) : Post()
class Image(var url: String, var caption: String) : Post()
class Video(var url: String, var timeDuration: Int, var encoding: String): Post()
}
Dies ist mit Enum-Klassen nicht möglich.
Sealed Classes und when
Sealed Classes werden häufig mit when-Ausdrücken verwendet, da jede der Unterklassen und ihre Typen als ein Fall fungieren. Darüber hinaus wissen wir, dass die Sealed Class die Typen einschränkt. Daher kann der else-Teil des when-Ausdrucks leicht entfernt werden. Das folgende Beispiel demonstriert dies.
sealed class Shape{
class Circle(var radius: Float): Shape()
class Square(var length: Int): Shape()
class Rectangle(var length: Int, var breadth: Int): Shape()
}
fun eval(e: Shape) =
when (e) {
is Shape.Circle -> println("Circle area is ${3.14*e.radius*e.radius}")
is Shape.Square -> println("Square area is ${e.length*e.length}")
is Shape.Rectangle -> println("Rectangle area is ${e.length*e.breadth}")
}
Führen wir die eval-Funktion in unserer Hauptfunktion aus, wie unten gezeigt.
fun main(args: Array<String>) {
var circle = Shape.Circle(4.5f)
var square = Shape.Square(4)
var rectangle = Shape.Rectangle(4,5)
eval(circle)
eval(square)
eval(rectangle)
//eval(x) //compile-time error.
}
//Following is printed on the console:
//Circle area is 63.585
//Square area is 16
//Rectangle area is 20
Hinweis: Das is-Modifier überprüft, ob die Klasse vom folgenden Typ ist. Das is-Modifier ist nur für Klassen erforderlich, nicht für Kotlin-Objekte, wie unten gezeigt:
sealed class Shape{
class Circle(var radius: Float): Shape()
class Square(var length: Int): Shape()
object Rectangle: Shape()
{
var length: Int = 0
var breadth : Int = 0
}
}
fun eval(e: Shape) =
when (e) {
is Shape.Circle -> println("Circle area is ${3.14*e.radius*e.radius}")
is Shape.Square -> println("Square area is ${e.length*e.length}")
Shape.Rectangle -> println("Rectangle area is ${Shape.Rectangle.length*Shape.Rectangle.breadth}")
}
Damit endet das Tutorial zur Kotlin Sealed Class.