علاقة "يحتوي على" (Has-A)
جزء من قسم البرمجة كائنية التوجه في رحلة Lua على Coddy. الدرس 49 من 70.
خلال هذه الدورة، استخدمت الوراثة لمشاركة السلوك بين الفئات: الكلب «هو» حيوان. لكن الوراثة ليست دائمًا الأداة المناسبة.
أحيانًا، لا تشترك الكائنات في شجرة عائلة؛ بل يحتوي كائنٌ ما ببساطة على كائنٍ آخر. يُسمّى هذا composition، وهو يحاكي علاقة «يمتلك».
تأمل سيارة Car. إن Car ليس نوعًا من engine. بل يمتلك engine. إن engine كائن object منفصل يوجد inside Car:
local Engine = {}
Engine.__index = Engine
function Engine:new(horsepower)
local obj = {horsepower = horsepower}
setmetatable(obj, Engine)
return obj
end
local Car = {}
Car.__index = Car
function Car:new(model, engine)
local obj = {
model = model,
engine = engine -- خزّن كائن Engine داخل Car
}
setmetatable(obj, Car)
return obj
endعند إنشاء سيارة، تمرّر كائن engine موجودًا إلى constructor الخاص بها:
local myEngine = Engine:new(200)
local myCar = Car:new("Sedan", myEngine)
print(myCar.engine.horsepower) -- 200السيارة لا ترث من المحرك. بل تحتفظ ببساطة بمرجع إليه. وهذا يحافظ على استقلالية كلتا الفئتين. يمكنك استبدال المحرك بمحرك مختلف، أو استخدام فئة المحرك نفسها في دراجة نارية.
يمنحك composition مرونة لا يمكن لـ inheritance توفيرها: فأنت تجمع الكائنات من أجزاء بدلًا من تقييدها ضمن تسلسل هرمي عائلي جامد.
التحدي
سهللنبنِ نظام كمبيوتر باستخدام التركيب! بدلاً من التوريث، ستنشئ Computer يحتوي على CPU بداخله: موضحًا علاقة "has-a".
ستنظم شيفرتك عبر ثلاثة ملفات:
CPU.lua: أنشئ فئة CPU مع مُنشئ:new(brand, speed)يخزّن اسم العلامة التجارية والسرعة بوحدة GHz. أضف أسلوب:getInfo()يعيد سلسلة نصية بالتنسيق:{brand} @ {speed}GHzComputer.lua: أنشئ فئة Computer whose constructor:new(model, cpu)يقبل اسم الطراز وكائن CPU. تخزّن Computer كائن CPU بداخلها (تركيب!). أضف أسلوب:describe()يطبع طراز الكمبيوتر ومعلومات CPU الخاصة به.main.lua: اجمع كل شيء معًا! اقرأ المدخلات الخاصة بعلامة CPU التجارية، وسرعة CPU، وطراز الكمبيوتر. أنشئ كائن CPU أولًا، ثم مرّره إلى مُنشئ Computer. وأخيرًا، استدعِ أسلوب:describe()الخاص بالكمبيوتر.
ستتلقى ثلاث مدخلات:
- علامة CPU التجارية (سلسلة نصية)
- سرعة CPU بوحدة GHz (رقم)
- اسم طراز الكمبيوتر (سلسلة نصية)
يجب أن يُظهر الناتج وصف الكمبيوتر، الذي يتضمن معلومات من CPU الموجود بداخله:
Model: {model}
CPU: {brand} @ {speed}GHzعلى سبيل المثال، إذا كانت المدخلات هي Intel و3.5 وWorkStation، فيجب أن يكون الناتج:
Model: WorkStation
CPU: Intel @ 3.5GHzلاحظ أن Computer لا يرث من CPU. إنه يحتفظ ببساطة بمرجع إلى أحدها. يصل أسلوب :describe() الخاص بـ Computer إلى بيانات CPU من خلال الكائن المخزّن، موضحًا كيف يتيح لك التركيب بناء كائنات معقدة من أجزاء أبسط!
جرّب بنفسك
-- main.lua
-- اجمع كل شيء معًا باستخدام التركيب
local CPU = require('CPU')
local Computer = require('Computer')
-- اقرأ المدخلات
local cpuBrand = io.read()
local cpuSpeed = tonumber(io.read())
local computerModel = io.read()
-- TODO: أنشئ كائن CPU بالعلامة التجارية والسرعة
-- TODO: أنشئ كائن Computer بالطراز وكائن CPU
-- TODO: استدعِ method الـ describe() الخاصة بالكمبيوتر لطباعة المخرجات
يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.
جميع دروس البرمجة كائنية التوجه
4مشروع: بنك رقمي
إعداد المشروعطريقة الإيداع7تعدد الأشكال وإعادة التعريف
إعادة تعريف الدوالاستدعاء دوال الفئة الأبDuck Typingواجهة مشتركةالتحقق من النوعمراجعة - أدوار الموظفين2نمط النموذج الأولي للفئات
مفهوم النموذج الأوليالربط باستخدام __indexالمنشئ :new()تهيئة الخصائصنسخ مستقلةملخص - مصنع السيارات5تحميل المعاملات في OOP
جمع الكائناتطرح الكائناتدمج الكائناتمقارنة الكائنات (<, >)مراجعة - رياضيات المحفظة8التغليف
اصطلاحات التسميةاستخدام Closures للخصوصيةالوصول عبر Closuresجداول للقراءة فقطمنطق التحقق من الصحةمراجعة - الخزنة الآمنة11أنماط التصميم (مبسط)
دوال المصنعجدول Singletonنمط الـ Iteratorالمراقب (المستمع)مراجعة - مصنع الـ Logger3حالة الكائن وسلوكه
متغيرات النسخةدالات الجلب (Getter Methods)دالات التعيين (Setter Methods)الخصائص المحسوبةتنسيق النصوصالتحقق من المساواةمراجعة - درجة الطالب6أساسيات الوراثة
إعداد الوراثةوراثة الـ Methodsتوسيع الـ Constructorإضافة Methods للابنالمشترك مقابل الفريدملخص - التسلسل الهرمي للأشكال9التركيب و Mixins
علاقة "يحتوي على" (Has-A)التفويض (Delegation)Mixins بسيطةتطبيق Mixins متعددةMixins مقابل الوراثةملخص - تجميع الروبوتتدرّب بنفسك: مترجم Lua عبر الإنترنت