إعداد الوراثة
جزء من قسم 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 للعثور على الجدول التالي للبحث فيه. يتيح ذلك للفئات الفرعية وراثة جميع دوال الفئة الأب تلقائيًا دون نسخها.
التحدي
سهللنقم ببناء أول هيكل وراثة لك! ستقوم بإنشاء علاقة فئة أب-ابن بسيطة حيث تعمل فئة 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"
يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.
جميع دروس Object Oriented Programming
4مشروع: بنك رقمي
إعداد المشروعطريقة الإيداع7تعدد الأشكال وإعادة التعريف
إعادة تعريف الدوالاستدعاء دوال الفئة الأبDuck Typingواجهة مشتركةالتحقق من النوعمراجعة - أدوار الموظفين2نمط النموذج الأولي للفئات
مفهوم النموذج الأوليالربط باستخدام __indexالمنشئ :new()تهيئة الخصائصنسخ مستقلةملخص - مصنع السيارات5تحميل المعاملات في OOP
جمع الكائناتطرح الكائناتدمج الكائناتمقارنة الكائنات (<, >)مراجعة - رياضيات المحفظة8التغليف
اصطلاحات التسميةاستخدام Closures للخصوصيةالوصول عبر Closuresجداول للقراءة فقطمنطق التحقق من الصحةمراجعة - الخزنة الآمنة11أنماط التصميم (مبسط)
دوال المصنعجدول Singletonنمط الـ Iteratorالمراقب (المستمع)مراجعة - مصنع الـ Logger3حالة الكائن وسلوكه
متغيرات النسخةدالات الجلب (Getter Methods)دالات التعيين (Setter Methods)الخصائص المحسوبةتنسيق النصوصالتحقق من المساواةمراجعة - درجة الطالب6أساسيات الوراثة
إعداد الوراثةوراثة الـ Methodsتوسيع الـ Constructorإضافة Methods للابنالمشترك مقابل الفريدملخص - التسلسل الهرمي للأشكال