الفئة المختومة في كوتلن

في هذا البرنامج التعليمي، سنقوم بالتعرف على فئة Kotlin Sealed. ما هي؟ وما هي استخداماتها؟ سنتناول كل هذه الأمور أدناه.

فئة Kotlin Sealed

ببساطة، كما يوحي الاسم، تكون الفئات المختومة مختومة أو مغلقة، مما يجعلها مقيدة. تُستخدم الفئات المختومة لتمثيل التسلسل الهرمي للفئات حيث يمكن للكائن أو القيمة أن تكون لها قيمة فقط من بين أحد الأنواع، مما يحدد تسلسل الأنواع الخاص بك. تُستخدم الفئات المختومة بشكل شائع في الحالات التي تعرف فيها القيمة المعطاة لتكون فقط من بين مجموعة معينة من الخيارات.

تنفيذ فئات Kotlin Sealed

يتم تنفيذ الفئات المختومة في 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 class Months(string: String){
January("Jan"), February(2),
}

تسمح فئات التعداد بنوع واحد فقط لجميع الثوابت. هنا حيث تأتي الفئات المختومة لإنقاذنا من خلال السماح بالعديد من المثيلات.

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()
}

هذا غير ممكن مع فئات التعداد.

الفئات المختومة والتعبير 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 يتحقق مما إذا كانت الفئة من النوع التالي. يُطلب المعدل 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