الدرس 22: الركيزة الثالثة لـ OOP: تعدد الأشكال (Polymorphism)
تعدد الأشكال يعني "أشكال متعددة". في Java، يسمح لنا بمعاملة كائنات من فئات مختلفة بطريقة موحدة، طالما أن تلك الفئات تشترك في أب مشترك أو واجهة (interface) واحدة.
1. تعدد الأشكال في وقت التجميع (زيادة تحميل الدوال - Method Overloading)
يتحقق ذلك من خلال وجود دوال متعددة داخل نفس الفئة تشترك في نفس الاسم ولكن لها تواقيع مختلفة (عدد أو أنواع مختلفة من المعلمات).
java public class Calculator { // دالة 1: تجمع رقمين صحيحين public int add(int a, int b) { return a + b; }
// دالة 2: تجمع ثلاثة أرقام صحيحة (overloaded)
public int add(int a, int b, int c) { return a + b + c; }
// دالة 3: تجمع رقمين عشريين (overloaded حسب النوع)
public double add(double a, double b) { return a + b; }
}
أثناء التجميع، يحدد المترجم أي دالة سيتم استدعاؤها بناءً على الوسائط المقدمة.
2. تعدد الأشكال في وقت التشغيل (إعادة تعريف الدوال - Method Overriding)
هذا هو جوهر التوزيع الديناميكي. يحدث عندما تتم الإشارة إلى كائن بواسطة متغير مرجعي من فئة الأب الخاصة به، وتكون الدالة التي يتم استدعاؤها هي دالة تم تجاوزها.
مفهوم رئيسي: يتم تحديد الدالة التي يتم تنفيذها من خلال نوع الكائن الفعلي (كائن وقت التشغيل)، وليس نوع المرجع.
java public class Vehicle { public void move() { System.out.println("Vehicle moves."); } } public class Truck extends Vehicle { @Override public void move() { System.out.println("Truck rumbles down the road."); } } public class Bicycle extends Vehicle { @Override public void move() { System.out.println("Bicycle pedals quietly."); } }
// تعدد الأشكال في وقت التشغيل: Vehicle v1 = new Truck(); // نوع المرجع هو Vehicle، نوع الكائن هو Truck Vehicle v2 = new Bicycle();
v1.move(); // يستدعي move الخاصة بـ Truck v2.move(); // يستدعي move الخاصة بـ Bicycle
تعدد الأشكال ضروري لكتابة كود مرن وقابل للتوسع، خاصة عند العمل مع مجموعات من كائنات متنوعة ولكنها مرتبطة.