Mixin هو طريقة لإعادة استخدام كود في عدة كلاسات مختلفة بدون الحاجة للوراثة التقليدية (extends)، ويُستخدم عندما نريد دمج سلوك (behavior) في كلاس دون جعله جزءًا من سلسلة الوراثة.
✅ الشكل العام:
mixinMixinName {// خصائص أو دوال قابلة لإعادة الاستخدام}
Dart
🎯 الهدف من mixin:
إعادة استخدام الكود دون الاعتماد على الوراثة.
تحقيق “الوراثة الأفقية” بدل “الوراثة العمودية”.
إعطاء الكلاسات وظائف إضافية بسهولة.
🧠 لماذا نستخدمه؟
المشكلة
الحل بـ mixin
Dart لا تدعم الوراثة المتعددة (multiple inheritance)
mixin تسمح بإضافة وظائف متعددة
تريد تشارك كود بين عدة كلاسات مختلفة
اكتب السلوك مرة، وادمجه بكل كلاس بسهولة
// كلاس أساسي يحتوي الخصائص المشتركةclassPerson {String name;Person(this.name);voidshowInfo() {print("الاسم: $name"); }}// Mixin لإضافة سلوك التسجيلmixinLogger {voidlog(String message) {print("LOG: $message"); }}// Admin يرث من Person ويستخدم mixin LoggerclassAdminextendsPersonwithLogger {Admin(String name) :super(name);voiddeleteUser(String userName) {log("تم حذف المستخدم: $userName"); }}// User يرث فقط من PersonclassUserextendsPerson {User(String name) :super(name);voidbrowse() {print("$name يتصفح الموقع 📄"); }}// برنامج التشغيلvoidmain() {Admin admin =Admin("أحمد المشرف"); admin.showInfo(); // الاسم: أحمد المشرف admin.deleteUser("ياسين"); // LOG: تم حذف المستخدم: ياسينprint('-----------------');User user =User("ياسين"); user.showInfo(); // الاسم: ياسين user.browse(); // ياسين يتصفح الموقع 📄}
Dart
✅ مثال 1: Mixin للصوت
mixinSoundMixin {voidmakeSound(String sound) {print("الصوت: $sound"); }}classDogwithSoundMixin {voidbark() {makeSound("هو هو 🐶"); }}classCatwithSoundMixin {voidmeow() {makeSound("مياو 🐱"); }}voidmain() {Dog dog =Dog(); dog.bark(); // الصوت: هو هو 🐶Cat cat =Cat(); cat.meow(); // الصوت: مياو 🐱}
Dart
✅ شرح المثال:
SoundMixin يحتوي على دالة واحدة.
Dog و Cat استخدموا with SoundMixin ليحصلوا على الدالة.
كل واحد منهم استخدمها بطريقته، دون وراثة من نفس الكلاس.
✅ الفرق بين extends و with و implements
الكلمة
معناها
تستخدم مع
extends
وراثة من كلاس واحد فقط
كلاس واحد
implements
تطبيق واجهة، يجب تنفيذ كل شيء
واجهات
with
دمج سلوك mixin
1 أو أكثر من mixins
✅ خصائص الـ mixin في Dart:
الخاصية
القيمة
✅ يمكن استخدامه مع أكثر من كلاس؟
نعم
✅ يمكن استخدام أكثر من mixin؟
نعم
❌ يحتوي على constructor؟
لا
✅ يمكنه احتواء خصائص ودوال؟
نعم
❌ يمكنه الوصول لـ super؟
لا، إلا في mixin on
✅ يدعم التكرار وإعادة الاستخدام؟
نعم جدًا
✅ مثال 2: Mixin للطباعة والتخزين
// كلاس أساسي يحتوي خصائص مشتركةclassDocument {finalString title;Document(this.title);voidshowTitle() {print("العنوان: $title"); }}// mixin للطباعةmixinPrintable {voidprintInfo() {print("📄 طباعة البيانات..."); }}// mixin للحفظmixinSaveable {voidsave() {print("💾 تم حفظ البيانات"); }}// Report يرث من Document ويضيف سلوك من Printable و SaveableclassReportextendsDocumentwithPrintable, Saveable {Report(String title) :super(title);voidgenerate() {print("📊 توليد التقرير..."); }}// التشغيلvoidmain() {Report report =Report("تقرير المبيعات"); report.showTitle(); // العنوان: تقرير المبيعات report.generate(); // 📊 توليد التقرير... report.printInfo(); // 📄 طباعة البيانات... report.save(); // 💾 تم حفظ البيانات}
Dart
✅ ملاحظة: ماذا يعني mixin on؟
mixin on تعني: هذا الـ mixin لا يمكن استخدامه إلا مع كلاس يورث من كلاس معين أو يحتوي خصائص محددة.