Menu
Coddy logo textTech
flag Ar iconالعربيةdown icon

إعداد الوراثة

جزء من قسم Object Oriented Programming في رحلة Lua على Coddy — الدرس 31 من 70.

حتى الآن، قمت ببناء فئات (classes) حيث يبحث كل كائن (object) عن الدوال (methods) في جدول نموذج مبدئي (prototype table) واحد. ولكن ماذا لو أردت أن تُبنى فئة على فئة أخرى؟ هنا يأتي دور الوراثة (inheritance) — حيث يمكن لفئة تابعة (child class) الوصول إلى كل شيء من فئة أب (parent class) مع إضافة ميزاتها الخاصة.

الفكرة الأساسية هي أن جدول الفئة نفسه يمكن أن يمتلك جدولاً وصفياً (metatable). فعندما لا تجد Lua شيئاً في الفئة الابنة، فإنها تبحث في __index الخاص بالجدول الوصفي للابنة—والذي يشير إلى الفئة الأب.

-- الفئة الأب
local Animal = {}
Animal.__index = Animal

function Animal:new()
    local obj = {}
    setmetatable(obj, Animal)
    return obj
end

function Animal:breathe()
    print("Breathing...")
end

إليك الآن إعداد الوراثة. نقوم بإنشاء فئة تابعة ونضبط الـ metatable الخاص بها للبحث في الفئة الأب:

-- فئة تابعة
local Dog = {}
Dog.__index = Dog
setmetatable(Dog, {__index = Animal})

هذا السطر الواحد—setmetatable(Dog, {__index = Animal})—ينشئ رابط الوراثة. عندما يستدعي مثيل (instance) من Dog طريقة (method) غير موجودة في Dog، تتحقق Lua من Animal.

تعمل سلسلة البحث بهذا الشكل: instance → Dog → Animal. تستخدم كل خطوة __index للعثور على الجدول التالي للبحث فيه. يتيح ذلك للفئات الفرعية وراثة جميع دوال الفئة الأب تلقائيًا دون نسخها.

challenge icon

التحدي

سهل

لنقم ببناء أول هيكل وراثة لك! ستقوم بإنشاء علاقة فئة أب-ابن بسيطة حيث تعمل فئة Machine كقاعدة، وترث فئة Robot منها.

ستقوم بتنظيم الكود الخاص بك عبر ثلاثة ملفات:

  • Machine.lua: قم بتعريف فئة الأب الخاصة بك باستخدام نمط الفئات القياسي. قم بتضمين منشئ :new() وطريقة :status() التي تطبع Machine is operational. لا تنسَ إعداد __index وإرجاع الفئة في نهاية الملف.
  • Robot.lua: قم بتعريف فئة الابن التي ترث من Machine. اطلب وحدة Machine، وقم بإعداد جدول Robot باستخدام __index الخاص به، وقم بإنشاء رابط الوراثة باستخدام setmetatable(Robot, {__index = Machine}). قم بتضمين منشئ :new() الذي ينشئ مثيلاً مع Robot كجدول ميتا (metatable) له.
  • main.lua: اجمع كل شيء معًا عن طريق طلب وحدة Robot الخاصة بك، وإنشاء مثيل Robot، واستدعاء طريقة :status() الموروثة.

المفهوم الأساسي هنا هو أن فئة Robot الخاصة بك لا تُعرف :status() بنفسها—بل ترث هذه الطريقة من Machine من خلال سلسلة جداول الميتا (metatable chain). عندما تستدعي :status() على مثيل Robot، ستبحث Lua في Robot أولاً، ولن تجدها، ثم تتبع رابط __index إلى Machine حيث تكتشف الطريقة.

يجب أن يكون مخرجك:

Machine is operational

يثبت هذا السطر الوحيد أن الوراثة تعمل—لقد نجح Robot الخاص بك في الوصول إلى طريقة محددة فقط في فئة الأب الخاصة به!

ورقة مرجعية

لإنشاء الوراثة في Lua، قم بتعيين الجدول الوصفي (metatable) لجدول الفئة ليشير إلى الفئة الأب باستخدام __index:

-- الفئة الأب
local Animal = {}
Animal.__index = Animal

function Animal:new()
    local obj = {}
    setmetatable(obj, Animal)
    return obj
end

function Animal:breathe()
    print("Breathing...")
end

-- الفئة الابن
local Dog = {}
Dog.__index = Dog
setmetatable(Dog, {__index = Animal})

يتم إنشاء رابط الوراثة باستخدام setmetatable(Dog, {__index = Animal}). يتيح ذلك لكائنات Dog الوصول إلى دوال Animal تلقائياً.

تتبع سلسلة البحث المسار التالي: instance ← الفئة الابن ← الفئة الأب. تستخدم كل خطوة __index للعثور على الجدول التالي للبحث فيه.

جرّب بنفسك

-- main.lua: اجمع كل شيء معًا

-- TODO: استدعِ وحدة Robot

-- TODO: أنشئ نسخة من Robot باستخدام Robot:new()

-- TODO: استدعِ طريقة :status() الموروثة على نسخة الروبوت الخاصة بك
-- يجب أن يطبع هذا "Machine is operational"
quiz iconاختبر نفسك

يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.

جميع دروس Object Oriented Programming