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

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

جزء من قسم البرمجة كائنية التوجه في رحلة Lua على Coddy. الدرس 31 من 70.

حتى الآن، أنشأتَ فئاتٍ يبحث فيها كل كائن عن الأساليب في جدول نموذج أولي واحد. لكن ماذا لو أردتَ أن تبني فئةٌ واحدة على أخرى؟ هنا يأتي دور inheritance: يمكن لفئة فرعية الوصول إلى كل شيء من فئة أصلية مع إضافة ميزاتها الخاصة.

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

-- الصنف الأب
local Animal = {}
Animal.__index = Animal

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

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

والآن إليك إعداد inheritance. ننشئ فئة Child ونضبط metatable الخاصة بها لتشير إلى Parent:

-- فئة فرعية
local Dog = {}
Dog.__index = Dog
setmetatable(Dog, {__index = Animal})

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

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

challenge icon

التحدي

سهل

لنَبْنِ أول تسلسل هرمي لـ inheritance خاص بك! ستنشئ علاقة بسيطة بين class أب وclass ابن، حيث تعمل class Machine كقاعدة، بينما ترث منها class Robot.

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

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

المفهوم الأساسي هنا هو أن class ‏Robot لا يعرّف :status() بنفسه. بل يرث هذا method من Machine عبر سلسلة metatable. عند استدعاء :status() على instance من Robot، سيبحث Lua أولًا في Robot، ولن يجده، ثم يتبع رابط __index إلى Machine حيث يكتشف الـ method.

يجب أن يكون الناتج:

Machine is operational

يثبت هذا السطر الوحيد أن inheritance تعمل. لقد تمكّن Robot بنجاح من الوصول إلى method معرّف في class الأب فقط!

جرّب بنفسك

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

-- TODO: استورد وحدة Robot

-- TODO: أنشئ مثيلاً من Robot باستخدام Robot:new()

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

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

جميع دروس البرمجة كائنية التوجه

تدرّب بنفسك: مترجم Lua عبر الإنترنت