במדריך זה, נתעקוב אחרי כיצד להשתמש ב- Kotlin Sealed Class. מהן? מהן השימושים שלהן? נטפל בכל אלו למטה.
Kotlin Sealed Class
במונחים פשוטים, כפי שהשם מרמז, קבוצות מסתומכות הן "מסתומכות" או סגורות, ולכן הן מוגבלות. קבוצות מסתומכות משמשות לייצוג של יררכיות של מחלקות מוגבלות בהן האובייקט או הערך יכול להיות מסוג רק אחד מתוך הסוגים, כלומר קבוצות אלו יוקעו את היררכיה שלך של סוגים. קבוצות מסתומכות נהוגות במקרים בהם ידוע שערך נתון יכול להיות רק מתוך סט נתון של אפשרויות.
יישום של Kotlin Sealed Classes
קבוצות מסתומכות ב-Kotlin מיושמות בדרך הבאה.
sealed class A{
class B : A()
class C : A()
}
כדי לציין קבוצה מסתומכת, יש להוסיף את המודיפיקטור sealed
. קבוצה מסתומכת לא יכולה להיות ממומנת. לכן הן אוטומטית מוגדרות כמופעלות. הדבר הבא לא יעבוד.
fun main(args: Array<String>)
{
var a = A() //compiler error. Class A cannot be instantiated.
}
ברירות מחדל של בנאי של קבוצה מסתומכת הן פרטיות. כל מחלקה מסתומכת נדרשת להוכרז באותו קובץ. קבוצות מסתומכות חשובות לאמיתות בטיחות סוג על ידי הגבלת סט הסוגים בזמן קומפילציה בלבד.
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.
}
יצירת מחלקה סגורה עם בנאיים.
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()
}
הוספת מחלקת נתונים ואובייקט במחלקה סגורה.
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()
}
ההבדל בין enum לבין מחלקות סגורות
ב-Kotlin, מחלקות סגורות ניתן להכניס להן את השם "Enum classes on steroids". מחלקות סגורות מאפשרות לנו ליצור מופעים עם סוגים שונים, להבדיל מ-Enums המגבילות אותנו לשימוש באותו סוג עבור כל קבוע Enum. הדבר הבא אינו אפשרי במחלקות Enum.
enum class Months(string: String){
January("Jan"), February(2),
}
מחלקות Enum מאפשרות רק סוג יחיד לכל הקבועים. כאן מגיעות מחלקות סגורות להציל אותנו על ידי הרשאה למספר מופעים.
sealed class Months {
class January(var shortHand: String) : Months()
class February(var number: Int) : Months()
class March(var shortHand: String, var number: Int) : Months()
}
איך ניתן להשתמש בתכונה זו של מחלקות סגורות בפרוייקטים שלכם? באפליקציה כמו מספרי חדשות, ניתן ליצור שלושה סוגי מחלקות שונים עבור פוסטים של מצב, תמונה, ווידאו כפי שמוצג למטה.
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()
}
דבר זה אינו אפשרי עם מחלקות Enum.
מחלקות סגורות ו-"when"
כיתות מסתומנות נהגו להשתמש בהצהרות when
מאחר וכל אחת מכיתות המשנה והסוגים שלהן פועלים כמקרה. יותר מזה, אנו יודעים שכיתה מסומנת מגבילה את הסוגים. לכן, חלקו של else
בהצהרת when
יכול להיסר בקלות. הדוגמה הבאה מדגימה זאת.
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("Rectagle area is ${e.length*e.breadth}")
}
בואו לבצע את פונקציית eval
בתוך הפונקציה main
שלנו כפי שמוצג למטה.
fun main(args: Array) {
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) //שגיאת זמן קומפילציה.
}
//הבא נדפס על המסך:
//שטח המעגל הוא 63.585
//שטח הריבוע הוא 16
//שטח המלבן הוא 20
הערה: המודיפייר is
בודק אם המחלקה היא מסוג מסוים. מודיפייר זה דרוש רק למחלקות ולא לאובייקטים ב-Kotlin כפי שמוצג למטה:
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}")
}
זה מסיים את מדריך כיתה מסומנת ב-Kotlin. הפניות: מסמכי Kotlin
Source:
https://www.digitalocean.com/community/tutorials/kotlin-sealed-class