الوراثة

تعديل
نسخ الدرس
تحميل الدرس

الوراثة

في الدروس السابقة تعلمنا كيف ننشئ أصنافاً ونستخدم initialize والموصّلات. لكن ماذا لو أردنا إنشاء أصناف متشابهة تشترك في بعض الخصائص والسلوكيات؟ هل نُكرر الشيفرة في كل صنف؟ بالطبع لا! هنا تأتي الوراثة (Inheritance).

ما هي الوراثة؟

الوراثة هي آلية تسمح لصنف (يُسمى الصنف الابن) بأن يرث خصائص وسلوكيات صنف آخر (يُسمى الصنف الأب).

مثال من الحياة الواقعية

فكّر في الحيوانات:

  • صنف أب: حيوان (له اسم، يأكل، ينام)
  • صنف ابن: كلب (يرث من حيوان + يضيف النباح)
  • صنف ابن: قط (يرث من حيوان + يضيف المواء)

الكلب والقط كلاهما حيوانات، لذا يشتركان في خصائص مثل الاسم والأكل والنوم. لكن لكل منهما سلوكه الخاص.

صيغة الوراثة

نستخدم الرمز < للوراثة:

مثال بسيط: الحيوان والكلب

بدون وراثة (الطريقة السيئة)

المشكلة: شيفرة مُكررة! إذا أردنا تعديل eat أو sleep، يجب تعديلها في كل صنف.

مع الوراثة (الطريقة الصحيحة)

الآن:

  • Dog يرث initialize, eat, sleep, و name من Animal
  • Dog يضيف bark كسلوك خاص به
  • لا تكرار للشيفرة!

إضافة أصناف ابن أخرى

إعادة تعريف الدوال (Method Overriding)

يمكن للصنف الابن إعادة تعريف دالة موروثة لتغيير سلوكها:

استدعاء دالة الأب بـ super

أحياناً نريد توسيع سلوك الأب بدلاً من استبداله كلياً. نستخدم super لاستدعاء دالة الأب:

أشكال super المختلفة

التحقق من الوراثة

مثال عملي: نظام الموظفين

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

الناتج:

قواعد الوراثة في روبي

1. الوراثة الفردية فقط

روبي تدعم وراثة فردية فقط (صنف واحد يرث من صنف أب واحد):

ملاحظة: لمشاركة الشيفرة بين أصناف غير متعلقة، نستخدم الوحدات (Modules) - سنتعلمها في الدرس القادم.

2. كل الأصناف ترث من Object

3. الموصّلات موروثة أيضاً

جدول مقارنة

المفهومالوصفمثال
الصنف الأبالصنف الذي يُورّثclass Animal
الصنف الابنالصنف الذي يرثclass Dog < Animal
<رمز الوراثةChild < Parent
superاستدعاء دالة الأبsuper(args)
Method Overrideإعادة تعريف دالة موروثةdef speak; "هاو!"; end
is_a?التحقق من النوع مع الوراثةdog.is_a?(Animal)
superclassالصنف الأب المباشرDog.superclass

أخطاء شائعة

1. نسيان super في initialize

الصحيح:

2. استدعاء super بالمُعاملات الخاطئة

الصحيح:

3. محاولة الوراثة المتعددة

4. استدعاء دالة غير موجودة في الأب

متى نستخدم الوراثة؟

استخدم الوراثة عندما:

  • يوجد علاقة "هو نوع من" (is-a relationship)
  • الصنف الابن هو تخصص من الصنف الأب
  • تريد مشاركة شيفرة بين أصناف متشابهة

لا تستخدم الوراثة عندما:

  • لا يوجد علاقة "هو نوع من"
  • تريد فقط مشاركة بعض الدوال (استخدم Modules)

ملخص

المفهومالوظيفة
class Child < Parentإنشاء صنف يرث من آخر
superاستدعاء دالة الأب
super(args)استدعاء مع مُعاملات محددة
Method Overrideإعادة تعريف دالة موروثة
is_a?التحقق من الوراثة
superclassمعرفة الصنف الأب
ancestorsسلسلة الوراثة كاملة

تمرين: نظام الحيوانات

حان وقت التطبيق! في محرر الشيفرة على اليسار:

المطلوب:

  1. أنشئ صنف Animal يحتوي على:

    • attr_reader :name
    • initialize(name)
    • speak تطبع "صوت غير معروف"
  2. أنشئ صنف Dog يرث من Animal:

    • إعادة تعريف speak لتطبع "هاو هاو!"
  3. أنشئ صنف Cat يرث من Animal:

    • إعادة تعريف speak لتطبع "مياو!"
  4. أنشئ كلباً اسمه "بوبي" وقطاً اسمه "ميشو"

  5. اطبع اسم كل حيوان ثم استدعِ speak

الناتج المتوقع:

تلميحات:

  • ابدأ بـ class Animal مع attr_reader :name و def initialize(name)
  • الكلب والقط يرثان: class Dog < Animal
  • استخدم puts داخل speak
  • لا تنسَ استدعاء .name للطباعة: puts dog.name

تذكّر: الوراثة تسمح بإنشاء تسلسل هرمي من الأصناف. الصنف الابن يرث كل شيء من الأب ويمكنه إضافة أو تعديل السلوكيات. استخدم super لاستدعاء دالة الأب عند الحاجة. في الدرس القادم سنتعلم الوحدات والـ Mixins لمشاركة الشيفرة بين أصناف غير متعلقة!