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

Mixin مقابل الوراثة (Inheritance)

جزء من قسم Object Oriented Programming في رحلة Dart على Coddy — الدرس 54 من 110.

بعد أن تعلمت الآن كيفية عمل الـ mixins، دعنا نوضح متى نستخدمها بدلاً من الوراثة (inheritance). يكمن الفرق الجوهري في العلاقة التي يعبران عنها.

يمثل التوريث علاقة "is-a". الـ Dog هو Animal. الفئة الفرعية هي نسخة متخصصة من الفئة الأب، ويمكنك فقط توسيع فئة واحدة.

الميكسنز (Mixins)، من ناحية أخرى، تمثل علاقة "يمكنه القيام بـ" (can-do). الـ Dog يمكنه السباحة، ولكن السباحة ليست هي ما يحدد الكلب.

// الوراثة: الكلب هو حيوان (Dog IS an Animal)
class Animal {
  String name;
  Animal(this.name);
}

class Dog extends Animal {
  Dog(String name) : super(name);
}

// Mixin: الكلب يستطيع السباحة (لكنه لا يُعرّف من خلال السباحة)
mixin Swimming {
  void swim() => print('Swimming');
}

class Dog extends Animal with Swimming {
  Dog(String name) : super(name);
}

استخدم الوراثة عندما تتشارك الأصناف هوية أساسية وتحتاج إلى constructors في الصنف الأب. استخدم الـ mixins عندما تريد إضافة قدرات إلى أصناف لا تشترك في سلف مشترك.

الميزةالوراثة (Inheritance)Mixin
العلاقةis-a (هو نوع من)can-do (يمكنه القيام بـ)
القيودأب واحد فقطعدة Mixins
الدوال البنائية (Constructors)مسموح بهاغير مسموح بها
حالة الاستخدامالتخصيص (Specialization)سلوك مشترك

الجزء الأفضل؟ يمكنك الجمع بين كليهما - توسيع فئة واحدة ودمج قدرات متعددة، مما يمنح فئاتك الميزات التي تحتاجها بالضبط.

challenge icon

التحدي

سهل

لنقم ببناء نظام عمال يوضح متى يتم استخدام الوراثة (inheritance) مقابل الـ mixins. ستقوم بإنشاء فئة أساسية لعلاقة "is-a" (هو عبارة عن) و mixins لإمكانيات "can-do" (يمكنه القيام بـ)، ثم تجمعهما معاً لإظهار كيف يعمل كلا النهجين معاً.

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

  • worker.dart: حدد الفئة الأساسية التي تثبت الهوية الجوهرية لجميع العمال:
    • فئة Worker مع خصائص String name و String department. قم بتضمين منشئ (constructor) يأخذ كلتا القيمتين. أضف دالة introduce() تطبع [name] works in [department]
  • skills.dart: حدد الـ mixins التي تمثل القدرات التي يمكن للعمال امتلاكها (علاقات "can-do"):
    • mixin باسم CanCode مع دالة writeCode() تطبع Writing code...
    • mixin باسم CanDesign مع دالة createDesign() تطبع Creating design...
    • mixin باسم CanManage مع دالة leadTeam() تطبع Leading the team...
  • main.dart: قم باستيراد كلا الملفين وإنشاء أنواع عمال متخصصة تجمع بين الوراثة والـ mixins:
    • فئة Developer ترث من Worker وتستخدم mixin الـ CanCode
    • فئة TechLead ترث من Worker وتستخدم كلا الـ mixins: CanCode و CanManage
    • أنشئ Developer باسم 'Alice' في قسم 'Engineering'
    • أنشئ TechLead باسم 'Bob' في قسم 'Engineering'
    • بالنسبة لـ Alice: استدعِ introduce() ثم writeCode()
    • اطبع سطراً فارغاً
    • بالنسبة لـ Bob: استدعِ introduce()، ثم writeCode()، ثم leadTeam()

لاحظ كيف أن كلاً من Developer و TechLead هما عمال (وراثة)، لكنهما يستطيعان القيام بأشياء مختلفة (mixins). يجمع TechLead بين قدرات متعددة دون الحاجة إلى الوراثة المتعددة.

المخرجات المتوقعة:

Alice works in Engineering
Writing code...

Bob works in Engineering
Writing code...
Leading the team...

ورقة مرجعية

تمثل الوراثة (Inheritance) علاقة "هو-نوع-من" ("is-a") (حيث تكون الفئة الفرعية نسخة متخصصة من الفئة الأب)، بينما تمثل الـ mixins علاقة "يمكنه-القيام-بـ" ("can-do") (إضافة قدرات دون تعريف الهوية).

// الوراثة: الكلب هو حيوان (Dog IS an Animal)
class Animal {
  String name;
  Animal(this.name);
}

class Dog extends Animal {
  Dog(String name) : super(name);
}

// Mixin: الكلب يمكنه السباحة (Dog CAN swim)
mixin Swimming {
  void swim() => print('Swimming');
}

class Dog extends Animal with Swimming {
  Dog(String name) : super(name);
}
الميزةالوراثة (Inheritance)الـ Mixin
العلاقةهو-نوع-من (is-a)يمكنه-القيام-بـ (can-do)
القيودأب واحد فقطعدة mixins
الدوال البنائية (Constructors)مسموح بهاغير مسموح بها
حالة الاستخدامالتخصص (Specialization)سلوك مشترك (Shared behavior)

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

class TechLead extends Worker with CanCode, CanManage {
  TechLead(String name, String department) : super(name, department);
}

جرّب بنفسك

import 'worker.dart';
import 'skills.dart';

// TODO: قم بإنشاء فئة Developer ترث من Worker وتستخدم mixin من نوع CanCode

// TODO: قم بإنشاء فئة TechLead ترث من Worker وتستخدم كلاً من mixins من نوع CanCode و CanManage

void main() {
  // TODO: قم بإنشاء Developer باسم 'Alice' في قسم 'Engineering'
  
  // TODO: قم باستدعاء introduce() ثم writeCode() لـ Alice
  
  // TODO: قم بطباعة سطر فارغ
  
  // TODO: قم بإنشاء TechLead باسم 'Bob' في قسم 'Engineering'
  
  // TODO: قم باستدعاء introduce() و writeCode() ثم leadTeam() لـ Bob
}
quiz iconاختبر نفسك

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

جميع دروس Object Oriented Programming