🔰 ما هو Polymorphism؟
كلمة Polymorphism تعني “تعدد الأشكال”.
هو أحد الركائز الأساسية في البرمجة الكائنية (OOP) إلى جانب:
- الوراثة (Inheritance)
- التغليف (Encapsulation)
- التجريد (Abstraction)
الهدف الأساسي: أن نستطيع استخدام نفس الدالة أو الخاصية بأشكال مختلفة حسب نوع الكائن.
🧠 الفكرة ببساطة:
تخيل أن لديك دالة speak() موجودة في كلاس Person، وتريد أن كل فئة من الأشخاص (مثل طالب، مدرس) تقول شيئًا مختلفًا.
نقوم بتعريف نفس الدالة في الكلاسات الأبناء بطريقة مختلفة، وعند استدعائها نُنفّذ السلوك المناسب لكل كائن.
✅ لماذا نستخدم Polymorphism؟
| الفائدة | التوضيح |
|---|---|
| 🔄 إعادة استخدام نفس الواجهة | يمكنك استدعاء نفس الدالة (speak()) على كائنات مختلفة وكل كائن يتصرف بطريقة مختلفة |
| 🧱 تقليل التكرار | بدل ما تعمل دالة مختلفة لكل نوع (speakAsStudent, speakAsTeacher…)، تستخدم واحدة |
| 🔧 تسهيل التوسعة | عند إضافة كائن جديد، فقط أُعيد تعريف الدالة بدون تغيير باقي الكود |
| 📦 فصل منطق التنفيذ | كل كائن يتكفل بسلوكه الخاص |
✅ أنواع الـ Polymorphism:
- Compile-time Polymorphism (Overloading): غير مدعومة في Dart مباشرة.
- Run-time Polymorphism (Overriding): مدعومة في Dart وهي الأكثر استخدامًا.
✅ أهم الأساسيات لتحقيق Polymorphism:
| العنصر | الشرح |
extends | لا بد أن يكون هناك وراثة |
@override | تُستخدم لإعادة تعريف دالة من الأب |
super | لاستدعاء دالة الأب إذا أردت دمج السلوك |
🔧 مثال بسيط جدًا
class Person {
void speak() {
print('👤 أنا شخص عادي.');
}
}
class Student extends Person {
@override
void speak() {
print('🎓 أنا طالب وأدرس.');
}
}
class Teacher extends Person {
@override
void speak() {
print('👨🏫 أنا مدرس وأشرح دروسي.');
}
}
void main() {
List<Person> people = [Student(), Teacher(), Person()];
for (var person in people) {
person.speak();
}
}Dart🔍 النتيجة:
🎓 أنا طالب وأدرس.
👨🏫 أنا مدرس وأشرح دروسي.
👤 أنا شخص عادي.Dart✅ لماذا؟
لأن الكود يستدعي speak() من كل كائن، و Dart تحدد أي نسخة من speak() تُنفّذ حسب نوع الكائن الحقيقي (Student أو Teacher أو Person).
✅ مثال تطبيقي: المنتجات
class Product {
void calculateDiscount() {
print('💸 الخصم: 5% للمنتجات العادية.');
}
}
class ElectronicProduct extends Product {
@override
void calculateDiscount() {
print('🔌 الخصم: 10% للمنتجات الإلكترونية.');
}
}
class FoodProduct extends Product {
@override
void calculateDiscount() {
print('🍏 الخصم: 2% للأطعمة.');
}
}
void main() {
List<Product> products = [Product(), ElectronicProduct(), FoodProduct()];
for (var product in products) {
product.calculateDiscount();
}
}Dart📌 النتيجة:
💸 الخصم: 5% للمنتجات العادية.
🔌 الخصم: 10% للمنتجات الإلكترونية.
🍏 الخصم: 2% للأطعمة.Dart✅ تمرين تطبيقي:
🔨 أنشئ الكلاسات التالية:
User– تحتوي على دالةdescribe()تطبع: “👤 مستخدم عام”Admin– ترث منUserوتطبع: “🛡️ مسؤول النظام”Guest– ترث منUserوتطبع: “👀 ضيف يطّلع فقط”
ثم قم بإنشاء قائمة تحتوي على كائنات من User, Admin, Guest ومر عليها باستخدام for واطبع النتائج باستخدام describe().
✅ أهم المفاهيم في Polymorphism:
| المفهوم | الشرح |
override | تعني إعادة تعريف الدالة من الأب |
dynamic dispatch | آلية في وقت التشغيل تحدد أي دالة يتم استدعاؤها حسب نوع الكائن الحقيقي |
interface-like behavior | جميع الكلاسات في Dart يمكن معاملتها كواجهات (Interfaces) |
✅ الخلاصة:
| النقطة | الشرح |
| Polymorphism | استخدام نفس الدالة بأشكال مختلفة حسب نوع الكائن |
| يستخدم في | الوراثة + override |
| فائدته | كتابة كود مرن وسهل التطوير والتوسعة |
| مثال | دالة speak() تختلف في Student و Teacher |