Menu
Coddy logo textTech
flag Ar iconالعربيةdown icon

الـ Sealed Classes (Java 17+)

جزء من قسم Object Oriented Programming في رحلة Java على Coddy — الدرس 52 من 87.

في لغة Java التقليدية، عندما تقوم بإنشاء فئة (class)، يمكن لأي فئة أخرى توسيعها (ما لم تقم بتمييزها كـ final). ولكن ماذا لو كنت تريد السماح بالوراثة، ولكن ليس من أي شخص؟ قدم إصدار Java 17 الفئات المختومة (sealed classes) لمنحك تحكماً دقيقاً في الفئات التي يمكنها توسيع فئتك.

يُصرح الفصل المختوم (sealed class) صراحةً عن فئاته الفرعية المسموح بها باستخدام الكلمات الرئيسية sealed و permits:

sealed class Shape permits Circle, Rectangle, Triangle {
    abstract double area();
}

final class Circle extends Shape {
    double radius;
    double area() { return Math.PI * radius * radius; }
}

final class Rectangle extends Shape {
    double width, height;
    double area() { return width * height; }
}

final class Triangle extends Shape {
    double base, height;
    double area() { return 0.5 * base * height; }
}

فقط Circle و Rectangle و Triangle يمكنها توسيع Shape. أي فئة أخرى تحاول توسيعه ستتسبب في خطأ في التجميع (compilation error).

يجب أن تستخدم كل فئة فرعية مسموح بها أحد المعدلات الثلاثة: final (لا يوجد تمديد إضافي)، أو sealed (يواصل سلسلة القيود)، أو non-sealed (يفتح المجال للتمديد غير المقيد):

sealed class Vehicle permits Car, Truck { }

final class Car extends Vehicle { }           // لا يمكن تمديدها
non-sealed class Truck extends Vehicle { }    // يمكن لأي شخص تمديد Truck

تعتبر الأصناف المختومة (Sealed classes) قوية بشكل خاص مع مطابقة الأنماط (pattern matching) في تعبيرات switch، حيث يعرف المترجم (compiler) جميع الأنواع الفرعية الممكنة ويمكنه التحقق من الشمولية. إنها مثالية عند نمذجة مجموعة ثابتة من الأنواع في مجال معين، مثل طرق الدفع، أو أنواع الاستجابة، أو الأشكال الهندسية.

challenge icon

التحدي

سهل

لنقم ببناء نظام إشعارات يوضح الفئات المختومة (sealed classes) من خلال تقييد أنواع الإشعارات التي يمكن أن توجد في تطبيقك. ستقوم بإنشاء تسلسل هرمي حيث يُسمح فقط بأنواع إشعارات محددة، وكل نوع يتعامل مع عملية التسليم بشكل مختلف.

ستقوم بتنظيم الكود الخاص بك عبر أربعة ملفات:

  • Notification.java: قم بإنشاء فئة مجردة مختومة (sealed abstract class) تعمل كقاعدة لجميع الإشعارات. يجب أن تسمح بوجود ثلاث فئات فرعية بالضبط: EmailNotification و SMSNotification و PushNotification. تحتاج فئتك المختومة إلى حقل محمي message (String)، ومنشئ (constructor) لتهيئته، ودالة getter للرسالة، ودالة مجردة deliver() تعيد String يصف كيفية إرسال الإشعار.
  • EmailNotification.java: قم بإنشاء فئة final ترث من Notification. يحتوي EmailNotification على حقل خاص إضافي recipient (String) لعنوان البريد الإلكتروني. يجب أن يأخذ المنشئ الخاص بها كلاً من الرسالة والمستلم، مع استدعاء منشئ الفئة الأب باستخدام super(). يجب أن تعيد الدالة deliver(): "Sending email to " + recipient + ": " + message
  • SMSNotification.java: قم بإنشاء فئة non-sealed ترث من Notification—وهذا يسمح لفئات أخرى بوراثتها إذا لزم الأمر في المستقبل. يحتوي SMSNotification على حقل خاص إضافي phoneNumber (String). يأخذ المنشئ الخاص بها الرسالة ورقم الهاتف. يجب أن تعيد الدالة deliver(): "Sending SMS to " + phoneNumber + ": " + message
  • PushNotification.java: قم بإنشاء فئة final ترث من Notification. يحتوي PushNotification على حقل خاص إضافي deviceId (String). يأخذ المنشئ الخاص بها الرسالة ومعرف الجهاز. يجب أن تعيد الدالة deliver(): "Sending push to device " + deviceId + ": " + message
  • Main.java: اجمع نظام الإشعارات الخاص بك معاً! ستتلقى أربعة مدخلات: رسالة (String)، وعنوان بريد إلكتروني (String)، ورقم هاتف (String)، ومعرف جهاز (String).

    قم بإنشاء واحد من كل نوع من أنواع الإشعارات باستخدام نفس الرسالة ولكن مع معلومات الاتصال الخاصة بكل منها. قم بتخزين الثلاثة جميعاً في مصفوفة من نوع Notification[] لإظهار تعدد الأشكال (polymorphism) مع الفئات المختومة. ثم قم بالمرور عبر المصفوفة واطبع نتيجة استدعاء deliver() لكل إشعار.

ستتلقى أربعة مدخلات بالترتيب: الرسالة، عنوان البريد الإلكتروني، رقم الهاتف، ومعرف الجهاز.

لاحظ كيف تقيد الفئة المختومة التسلسل الهرمي—فقط الفئات الثلاث المسموح بها يمكنها وراثة Notification. يجب على كل فئة فرعية أن تعلن عن نفسها كـ final أو sealed أو non-sealed. يمنحك هذا تحكماً كاملاً في تسلسل الأنواع الهرمي مع الاستمرار في تمكين تعدد الأشكال!

ورقة مرجعية

يُقيد الفصل المختوم (sealed class) الفئات التي يمكنها توسيعه باستخدام الكلمات المفتاحية sealed و permits:

sealed class Shape permits Circle, Rectangle, Triangle {
    abstract double area();
}

فقط الفئات المدرجة في permits يمكنها توسيع الفصل المختوم. أي فئة أخرى تحاول توسيعه ستتسبب في خطأ برمجِي أثناء التجميع (compilation error).

يجب أن تستخدم كل فئة فرعية مسموح بها أحد المعدلات الثلاثة التالية:

  • final - يمنع التوسيع الإضافي
  • sealed - يواصل سلسلة القيود مع فئاته الفرعية المسموح بها
  • non-sealed - يفتح التسلسل الهرمي للتوسيع غير المقيد
sealed class Vehicle permits Car, Truck { }

final class Car extends Vehicle { }           // لا يمكن توسيعه
non-sealed class Truck extends Vehicle { }    // يمكن لأي شخص توسيع Truck

تُعد الفصول المختومة (Sealed classes) مفيدة لنمذجة مجموعة ثابتة من الأنواع في مجال معين، مثل طرق الدفع، أو أنواع الاستجابة، أو الأشكال الهندسية. وهي تعمل بشكل جيد مع مطابقة الأنماط (pattern matching) في تعبيرات switch، حيث يعرف المترجم (compiler) جميع الأنواع الفرعية الممكنة.

جرّب بنفسك

import java.util.Scanner;

class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        
        // قراءة المدخلات الأربعة
        String message = scanner.nextLine();
        String email = scanner.nextLine();
        String phoneNumber = scanner.nextLine();
        String deviceId = scanner.nextLine();
        
        // TODO: إنشاء واحد من كل نوع من أنواع الإشعارات باستخدام نفس الرسالة
        // - EmailNotification مع message و email
        // - SMSNotification مع message و phoneNumber
        // - PushNotification مع message و deviceId
        
        // TODO: تخزين جميع الإشعارات الثلاثة في مصفوفة Notification[]
        // هذا يوضح تعدد الأشكال (polymorphism) مع الفئات المختومة (sealed classes)
        
        // TODO: التكرار عبر المصفوفة وطباعة نتيجة deliver()
        // لكل إشعار
        
    }
}
quiz iconاختبر نفسك

يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.

جميع دروس Object Oriented Programming