إضافة Methods للابن
جزء من قسم Object Oriented Programming في رحلة Lua على Coddy — الدرس 34 من 70.
يسمح التوريث للأصناف الفرعية بالوصول إلى دوال الصنف الأب، لكن القوة الحقيقية تأتي من إضافة دوال جديدة يمتلكها الصنف الفرعي فقط. يمكن لـ Dog القيام بكل ما يمكن لـ Animal القيام به، بالإضافة إلى أشياء فريدة للكلاب - مثل النباح.
إضافة طريقة خاصة بالابن (child-specific method) هو أمر مباشر: ما عليك سوى تعريفها في جدول فئة الابن (child class table). وبما أن النسخ (instances) تبحث عن الطرق في فئتها الخاصة أولاً، فإنها ستجد الطريقة الجديدة دون التأثير على الأب (parent).
local Animal = {}
Animal.__index = Animal
function Animal:new(name)
local obj = {name = name}
setmetatable(obj, Animal)
return obj
end
function Animal:breathe()
print(self.name .. " is breathing")
end
-- Dog يرث من Animal
local Dog = {}
Dog.__index = Dog
setmetatable(Dog, {__index = Animal})
function Dog:new(name)
local obj = Animal.new(Animal, name)
setmetatable(obj, Dog)
return obj
end
-- طريقة جديدة فقط في Dog
function Dog:bark()
print(self.name .. " says: Woof!")
endالآن يمكن لنماذج Dog استخدام كل من الأساليب الموروثة والفريدة:
local buddy = Dog:new("Buddy")
buddy:breathe() -- المخرجات: Buddy is breathing (موروث)
buddy:bark() -- المخرجات: Buddy says: Woof! (خاص بالابن فقط)تظل الفئة الأب (parent class) دون تغيير—فإن استدعاء :bark() على كائن Animal عادي سيفشل لأن هذه الدالة (method) غير موجودة هناك. هذه هي الطريقة التي تتيح لك بها الوراثة (inheritance) تخصيص السلوك مع الحفاظ على الوظائف المشتركة في مكان واحد.
التحدي
سهللنقم ببناء تسلسل هرمي للحيوانات الأليفة حيث تمتلك القطط قدرتها الخاصة! ستقوم بإنشاء فئة أب Pet وفئة ابن Cat، حيث ترث Cat كل شيء من Pet ولكن لديها أيضاً طريقة (method) فريدة لا تستطيع القيام بها إلا القطط.
ستقوم بتنظيم الكود الخاص بك عبر ثلاثة ملفات:
Pet.lua: قم بتعريف فئة الأب باستخدام منشئ:new(name)يقوم بتخزين اسم الحيوان الأليف. قم بتضمين طريقة:greet()تطبع اسم الحيوان الأليف متبوعاً بـsays hello. قم بإعداد نمط الفئة القياسي وأعد الفئة.Cat.lua: قم بتعريف فئة الابن التي ترث من Pet. يجب أن يستدعي منشئ:new(name)الخاص بـ Cat منشئ الأب لتهيئة الاسم، ثم إعادة ربط الـ metatable بـ Cat. أضف طريقة:purr()خاصة بالابن تطبع اسم القطة متبوعاً بـpurrs contentedly. هذه الطريقة موجودة فقط في Cat — ولا تملكها Pet!main.lua: اطلب وحدة Cat، واقرأ اسماً من المدخلات، وأنشئ مثيلاً (instance) من Cat، وأثبت أنه يمكنه استخدام كل من طريقة:greet()الموروثة وطريقته الفريدة:purr().
ستتلقى مدخلاً واحداً: اسم القطة.
في ملفك الرئيسي، أنشئ Cat بالاسم المعطى، ثم استدعِ :greet() متبوعة بـ :purr() في أسطر منفصلة.
على سبيل المثال، إذا كان الإدخال هو Whiskers، فيجب أن يكون الإخراج:
Whiskers says hello
Whiskers purrs contentedlyيأتي السطر الأول من طريقة :greet() الموروثة والمحددة في Pet، بينما يأتي السطر الثاني من طريقة :purr() الموجودة فقط في Cat. يوضح هذا كيف يمكن لفئات الأبناء القيام بكل ما يمكن لآبائهم القيام به، بالإضافة إلى سلوكياتهم المتخصصة!
ورقة مرجعية
يمكن للأصناف الفرعية (Child classes) إضافة دوال (methods) جديدة تمتلكها هي فقط، مع استمرار وراثة جميع دوال الصنف الأب (parent methods). تبحث الكائنات (Instances) عن الدوال في صنفها الخاص أولاً، ثم تعود إلى الصنف الأب.
لإضافة دالة خاصة بالصنف الفرعي، قم بتعريفها في جدول الصنف الفرعي:
local Animal = {}
Animal.__index = Animal
function Animal:new(name)
local obj = {name = name}
setmetatable(obj, Animal)
return obj
end
function Animal:breathe()
print(self.name .. " is breathing")
end
-- Dog يرث من Animal
local Dog = {}
Dog.__index = Dog
setmetatable(Dog, {__index = Animal})
function Dog:new(name)
local obj = Animal.new(Animal, name)
setmetatable(obj, Dog)
return obj
end
-- دالة خاصة بالصنف الفرعي
function Dog:bark()
print(self.name .. " says: Woof!")
endيمكن لكائنات الصنف الفرعي استخدام كل من الدوال الموروثة والفريدة:
local buddy = Dog:new("Buddy")
buddy:breathe() -- موروثة من Animal
buddy:bark() -- دالة خاصة بالصنف الفرعي فقطيظل الصنف الأب غير متأثر—فهو لا يملك الوصول إلى الدوال الخاصة بالصنف الفرعي.
جرّب بنفسك
-- main.lua: إنشاء قطة وتوضيح الوراثة
local Cat = require('Cat')
-- قراءة اسم القطة من المدخلات
local name = io.read()
-- TODO: إنشاء كائن (instance) من القطة بالاسم المعطى
-- TODO: استدعاء طريقة :greet() الموروثة (من Pet)
-- TODO: استدعاء طريقة :purr() الخاصة بالقطة
يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.
جميع دروس 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 للابنالمشترك مقابل الفريدملخص - التسلسل الهرمي للأشكال