🔰 ما هو 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 |