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

إضافة 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) تخصيص السلوك مع الحفاظ على الوظائف المشتركة في مكان واحد.

challenge icon

التحدي

سهل

لنقم ببناء تسلسل هرمي للحيوانات الأليفة حيث تمتلك القطط قدرتها الخاصة! ستقوم بإنشاء فئة أب 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() الخاصة بالقطة
quiz iconاختبر نفسك

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

جميع دروس Object Oriented Programming