طَبِّقْهاتعلّم المبدأ، وطبّقه بيدكمقرر 111 · أساسيات برمجة الحاسب
الدرس 24 · الوحدة 5: البرمجة الشيئية

تعدد الأشكال

أمر واحد، وكل كائن ينفّذه بطريقته. ⏱ نحو 20 دقيقة.

shape.area()
بعد هذا الدرس ستستطيع أن:
  • تشرح تعدد الأشكال بمثال من الحياة.
  • تكتب دالة بالاسم نفسه في كلاسات مختلفة.
  • تستدعي الدالة نفسها على قائمة كائنات مختلفة.
  • تلخّص مبادئ البرمجة الشيئية الأربعة.

١أمر واحد، وأشكال كثيرة

تقول للطلاب «قدّموا أنفسكم»، فيقول كل واحد كلامًا مختلفًا. الأمر واحد، والتنفيذ يختلف حسب الشخص. هذا هو تعدد الأشكال: دالة بالاسم نفسه في كلاسات مختلفة، وكل كلاس ينفّذها بطريقته.

main.py
class Dog:    def speak(self):        print("هو هو") class Cat:    def speak(self):        print("مياو") for animal in [Dog(), Cat(), Dog()]:    animal.speak()
Shell×
>>> %Run main.py
هو هو
مياو
هو هو
>>>

الحلقة لا تسأل «هل هذا كلب أم قط؟». تكتب animal.speak() فقط، وكل كائن يعرف ما يفعله.

٢مع الوراثة: الأشكال الهندسية

غالبًا نجمع تعدد الأشكال مع الوراثة: الأب يحدد اسم الدالة، وكل ابن يعيد تعريفها بطريقته:

main.py
class Shape:    def area(self):        return 0 class Square(Shape):    def __init__(self, side):        self.side = side    def area(self):        return self.side * self.side class Circle(Shape):    def __init__(self, r):        self.r = r    def area(self):        return round(3.14 * self.r * self.r, 2) shapes = [Square(4), Circle(2), Square(3)]for s in shapes:    print(s.area())
Shell×
>>> %Run main.py
16
12.56
9
>>>

٣لماذا هو مفيد؟

لو أضفنا شكلًا جديدًا (مستطيلًا مثلًا) فإننا نكتب كلاسه فقط، ولا نغيّر الحلقة أبدًا. قارن:

✗ خطأ
main.py
for s in shapes:    if type(s) == Square:        print(s.side * s.side)    elif type(s) == Circle:        print(3.14 * s.r * s.r)
✓ صواب
main.py
for s in shapes:    print(s.area())

في الطريقة الأولى نعدّل الحلقة مع كل شكل جديد. في الثانية الحلقة ثابتة، وكل شكل يحسب مساحته بنفسه.

٤ملخص البرمجة الشيئية

المبدأالفكرةفي بايثون
الكلاس والكائنقالب ونسخ منهclass و Car()
التغليفحماية البياناتself.__balance
الوراثةالابن يأخذ من الأبclass Student(Person)
تعدد الأشكالأمر واحد وتنفيذ مختلفدالة بالاسم نفسه في كل كلاس
📎 للاستزادة (اختياري): أنت تستخدم تعدد الأشكال منذ البداية

الدالة len تعمل مع النص ومع القائمة، والعلامة + تجمع الأعداد وتلصق النصوص. أمر واحد وسلوك يختلف حسب النوع.

توقّع وتحقّق

ما معنى تعدد الأشكال؟

أمر واحد، وتنفيذ مختلف.

في الحلقة for s in shapes: print(s.area()) من يحدد طريقة حساب المساحة؟

كل كلاس يعرّف area بطريقته.

عند إضافة شكل جديد، ماذا نكتب؟

الحلقة لا تتغيّر.

أي مبدأ يحمي البيانات داخل الكائن؟

التغليف.

الخلاصة

تحدٍّ برمجي: الموظفون والرواتب

متقدم

اكتب كلاسين: Employee و Manager، لكل منهما __init__ تحفظ الراتب الأساسي، ودالة pay. موظف عادي: pay تُرجع الراتب كما هو. المدير: pay تُرجع الراتب + 2000. ضع في قائمة موظفًا براتب 5000 ومديرًا براتب 7000، واطبع pay لكل منهما بحلقة، ثم المجموع.

المطلوب:
  • Manager يرث من Employee.
  • أعد تعريف pay في Manager.
  • الحلقة تستدعي p.pay() فقط.
  • اطبع: المجموع: ثم القيمة.

ابدأ من هذا الكود، واضغط ▶ شغّل هنا لتكتب حلّك وتجرّبه مباشرة:

main.py
class Employee:    def __init__(self, salary):        self.salary = salary
المطلوب×
5000
9000
المجموع: 14000
💡 تلميح 1
class Manager(Employee):
💡 تلميح 2
return self.salary + 2000

حاول بنفسك أولًا؛ للمسألة أكثر من حلّ صحيح.

main.py
class Employee:    def __init__(self, salary):        self.salary = salary     def pay(self):        return self.salary class Manager(Employee):    def pay(self):        return self.salary + 2000 staff = [Employee(5000), Manager(7000)]total = 0for p in staff:    print(p.pay())    total += p.pay()print("المجموع:", total)
انتقل إلى تقييم الدرساختيار من متعدد، وصح وخطأ، وأكمل الفراغ، وتتبّع الناتج.ابدأ التقييم ←