sealed class و interface في Kotlin — ما هي، بناء الجملة والتطبيق

المؤلف: IT Sectr نُشر: 2026-06-20 وقت القراءة: 11 دق

sealed class و sealed interface في Kotlin هما آليتان للتسلسل الهرمي المقيد للأنواع، حيث تكون جميع الفئات الفرعية المحتملة معروفة في وقت الترجمة. على عكس الفئات المجردة العادية، تضمن sealed class معالجة شاملة لجميع المتغيرات في تعبير when. وفقًا لوثائق JetBrains Kotlin Language Guide (2026)، تعد الأنواع sealed الأساس لنمذجة الحالات وشاشات واجهة المستخدم وأنواع النتائج في مشاريع Kotlin.

النقاط الرئيسية

  • sealed — تسلسل هرمي مقيد حيث تكون جميع الفئات الفرعية معروفة في وقت الترجمة
  • when — معالجة شاملة لجميع الفئات الفرعية بدون كتلة else إلزامية
  • sealed interface — أُضيف في Kotlin 1.5 لتسلسلات هرمية مرنة بدون قيود على الوراثة
  • الترجمة — خطأ في الترجمة عند عدم اكتمال when للأنواع sealed
  • التسلسل الهرمي — يجب أن تكون جميع الفئات الفرعية في نفس الملف أو داخل فئة sealed

ما هي sealed class و sealed interface؟

sealed class هي فئة مجردة مع تقييد: يجب الإعلان عن جميع فئاتها الفرعية المباشرة في نفس الملف الذي توجد فيه sealed class. هذا التقييد يجعل التسلسل الهرمي مغلقًا (sealed) — لا يمكن لأي كود خارج الملف إضافة فئة فرعية جديدة.

sealed interface، التي أُضيفت في Kotlin 1.5، توفر نفس الضمان ولكن مع مرونة الواجهة: يمكن تنفيذ sealed interface بواسطة فئات متعددة أو كائنات أو واجهات أخرى في ملف واحد. على عكس sealed class، لا تحتوي sealed interface على تقييد الوراثة الفردية — يمكن للفئة تنفيذ واجهات sealed متعددة في وقت واحد.

وفقًا لـ Kotlin Evolution and Roadmap (2026)، أُضيفت sealed interface بناءً على طلب المجتمع لنمذجة أكثر مرونة. الدافع الرئيسي هو القدرة على الجمع بين التسلسلات الهرمية للأنواع المستقلة دون وراثة متعددة للفئات.

بناء جملة sealed class

يبدأ إعلان sealed class بالمُعدِّل sealed قبل class. يتم الإعلان عن الفئات الفرعية في نفس الملف.

kotlin
sealed class NetworkResult {
    data class Success(val data: String) : NetworkResult()
    data class Error(val message: String) : NetworkResult()
    object Loading : NetworkResult()
}

يمكن أن تحتوي كل فئة فرعية من sealed class على خصائصها وطرقها الخاصة. Loading هو كائن فردي (object)، Success و Error هما data classes مع معلمات. يعرف المترجم جميع المتغيرات الثلاثة ويتحقق من اكتمالها عند استخدامها في when.

الفئات sealed المتداخلة

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

kotlin
sealed class UiState {
    object Idle : UiState()
    object Loading : UiState()
    data class Content(val items: List<Item>) : UiState()
    data class Error(val exception: Throwable) : UiState()
}

بناء جملة sealed interface (Kotlin 1.5+)

يتم الإعلان عن sealed interface بشكل مشابه لـ sealed class، ولكنه يسمح بتنفيذ واجهات sealed متعددة في فئة واحدة.

kotlin
sealed interface Action
sealed interface Loggable

data class Navigate(val route: String) : Action, Loggable
data class ShowToast(val text: String) : Action
object GoBack : Action, Loggable

تقوم فئة Navigate بتنفيذ واجهتين sealed في وقت واحد — Action و Loggable. هذا مستحيل مع sealed class بسبب تقييد الوراثة الفردية. توفر sealed interface مرونة الجمع بين التسلسلات الهرمية المستقلة.

متى تختار sealed interface بدلاً من sealed class

sealed interface مفضلة عندما لا يتطلب التسلسل الهرمي حالة مشتركة أو مُنشئ. وفقًا لإرشادات JetBrains Kotlin Guidelines (2026)، يجب استخدام sealed interface افتراضيًا لجميع التسلسلات الهرمية الجديدة حيث لا تكون هناك حاجة إلى مُنشئ مشترك، مما يجعل الكود أكثر مرونة للتوسعات المستقبلية.

المعالجة الشاملة في when

الميزة الرئيسية للأنواع sealed هي المعالجة الشاملة في تعبير when. يتحقق المترجم من تغطية جميع الفئات الفرعية المحتملة.

kotlin
fun handleResult(result: NetworkResult): String = when (result) {
    is NetworkResult.Success -> "Data: ${result.data}"
    is NetworkResult.Error -> "Error: ${result.message}"
    is NetworkResult.Loading -> "Loading..."
    // else غير مطلوب — المترجم يعلم أن جميع المتغيرات مغطاة
}

إذا أضاف المطور فئة فرعية جديدة إلى التسلسل الهرمي sealed لكنه نسي معالجتها في when — سيرمي المترجم خطأ. هذه سلامة على مستوى الأنواع، غير متاحة مع التسلسلات الهرمية المفتوحة التي تستخدم فرع else.

وفقًا لـ Google Android Developers (2026)، الفئات sealed هي الطريقة الموصى بها لنمذجة حالة واجهة المستخدم في Jetpack Compose. يمنع الفحص الشامل لـ when الحالات التي لم يعالج فيها المطور جميع المتغيرات المحتملة لعرض الشاشة.

مقارنة sealed class مع enum class

غالبًا ما يتم الخلط بين enum class و sealed class، لكن لهما أغراض وقدرات مختلفة.

الخاصيةsealed classenum class
الحالاتمتعددة (data class)، واحدة (object)واحدة بالضبط لكل ثابت
الخصائصمختلفة لكل فئة فرعيةنفسها لجميع الثوابت
الوراثةنعم (من sealed class)لا (نهائي ضمنيًا)
المُنشئيمكن أن يحتوي على معلماتمشترك فقط لجميع الثوابت
التسلسل الهرميمقيد، sealedمجموعة ثابتة من الثوابت

يعتمد الاختيار بين sealed class و enum class على المهمة. إذا كانت المتغيرات لا تحمل بيانات إضافية — استخدم enum. إذا كان كل متغير يحتوي على حقول فريدة — استخدم sealed class أو sealed interface.

سيناريوهات الاستخدام العملية

تُستخدم الأنواع sealed في مشاريع Kotlin لمجموعة من السيناريوهات القياسية حيث تكون النمذجة الآمنة للأنواع مطلوبة.

حالة واجهة المستخدم في Jetpack Compose

يمكن أن تحتوي كل شاشة Compose على sealed class UiState تصف جميع الحالات المحتملة: Idle، Loading، Content(data)، Error(exception). يضمن تعبير when معالجة جميع الحالات.

نتائج طلبات الشبكة

NetworkResult مع المتغيرات Success، Error، Loading هو نمط قياسي في مشاريع Kotlin مع Retrofit و Ktor. توفر sealed class معالجة آمنة لكل نتيجة من نتائج الطلب.

التنقل في المشاريع متعددة الوحدات

sealed interface لمسارات التنقل تسمح للوحدات بالإعلان عن مساراتها الخاصة مع البقاء ضمن تسلسل هرمي موحد. هذا يلغي الأخطاء المتعلقة بالمسارات غير المعروفة في وقت الترجمة.

وفقًا لـ KotlinConf (2025)، فإن sealed class و sealed interface هما أساس التصميم الآمن للأنواع في تطبيقات Kotlin الحديثة. يتم دمجهما مع data class لنمذجة هياكل المجال المعقدة دون فقدان الأمان في وقت الترجمة.

الأسئلة المتكررة

أين يجب الإعلان عن الفئات الفرعية لـ sealed class؟

جميع الفئات الفرعية المباشرة لـ sealed class يجب الإعلان عنها في نفس الملف. بالنسبة لـ sealed interface تنطبق نفس القاعدة — التطبيقات في ملف واحد.

هل يمكن أن يكون لـ sealed interface تطبيقات في ملف مختلف؟

لا، قاعدة الملف الواحد تنطبق أيضًا على sealed interface. يجب أن تكون جميع التطبيقات في الملف الذي تم الإعلان فيه عن sealed interface.

ما الفرق بين sealed class و sealed interface؟

sealed interface ليس لها حالة أو مُنشئ وتسمح بالتطبيق المتعدد. يمكن أن تحتوي sealed class على مُنشئ وحالة مشتركة، لكن الفئة يمكنها أن ترث sealed class واحدًا فقط.

كيف تساعد الفئات sealed في تعبيرات when؟

يتحقق المترجم من اكتمال when: إذا لم يتم معالجة جميع الفئات الفرعية، لا يتم ترجمة الكود. هذا يلغي أخطاء وقت التشغيل ويجعل الكود أكثر أمانًا.

هل يمكن أن تحتوي sealed class على مُنشئ؟

نعم، يمكن أن تحتوي sealed class على مُنشئ (خاص افتراضيًا). يمكن لجميع الفئات الفرعية تمرير المعلمات إلى هذا المُنشئ عبر super().

الخلاصة

  • sealed class — تسلسل هرمي مقيد مع فئات فرعية معروفة في وقت الترجمة
  • sealed interface — بديل مرن (Kotlin 1.5+) مع دعم التطبيق المتعدد
  • when — معالجة شاملة مع فحص المترجم، بدون حاجة إلى else
  • ملف واحد — جميع الفئات الفرعية والتطبيقات يجب أن تكون في نفس ملف النوع sealed
  • النمذجة — حالات واجهة المستخدم، نتائج الشبكة، التنقل، أنظمة الأحداث
  • الأمان — إضافة فئة فرعية جديدة بدون معالجة في when يسبب خطأ في الترجمة
  • الاختيار — sealed interface مفضلة افتراضيًا، sealed class عند الحاجة إلى حالة مشتركة

سنقوم بتطوير تطبيق جوال جاهز

تقدم IT Sectr تطبيقات iOS وAndroid للشركات الناشئة والشركات منذ عام 2017. سوف نقدم لك النصح ونقترح أفضل حل.

مناقشة المشروع

اقرأ أيضًا