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

Mixins مقابل الوراثة

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

لقد تعلّمت طريقتين لمشاركة السلوك: تنشئ الوراثة علاقة «is-a» من خلال سلسلة النماذج الأولية، بينما تنسخ المزيجات الدوال مباشرةً إلى فئة. لكن متى ينبغي أن تستخدم كل نهج؟

استخدم الوراثة عندما تشترك الكائنات في هوية أساسية. إن Bird هو Animal. من المنطقي أن يرث Bird سلوكيات الحيوانات الأساسية مثل :eat() أو :sleep(). العلاقة دائمة وتحدد ماهية الكائن بشكل أساسي.

استخدم mixins عندما تريد إضافة قدرة لا تحدد الهوية الأساسية للكائن.

ليست كل birds قادرة على fly: طيور البطريق والنعام هي birds، لكنها لا تقوم بـ fly. إن الطيران هو capability، وليس سمةً تحدد كونها bird. يتيح لك نمط Flyable mixin إضافة الطيران إلى birds التي تحتاج إليه، من دون فرضه على all منها.

يعمل النهجان معًا بشكل رائع:

-- Bird يرث من Animal (علاقة is-a)
local Bird = {}
Bird.__index = Bird
setmetatable(Bird, {__index = Animal})

-- Flyable هي قدرة (mixin)
local Flyable = {}
function Flyable:fly()
    print(self.name .. " soars through the sky!")
end

-- طبّق الـ mixin فقط على الطيور التي تستطيع الطيران
applyMixin(Bird, Flyable)

يمنحك هذا النمط أفضل ما في العالمين: تسلسلاً هرميًا واضحًا للفئات من أجل الهوية المشتركة، بالإضافة إلى إمكانات مرنة يمكن مزجها عند الحاجة.

challenge icon

التحدي

سهل

لنبنِ نظامًا بيئيًا صغيرًا من الكائنات يوضّح متى نستخدم الوراثة ومتى نستخدم الخلطات البرمجية! ستنشئ فئة أساسية Animal، وBird ترث منها، وخلطة Swimmable، لأن جميع الطيور حيوانات، لكن ليست جميع الطيور قادرة على السباحة.

ستنظّم شيفرتك عبر أربعة ملفات:

  • Animal.lua: أنشئ فئة Animal الأساسية مع مُنشئ :new(name) يخزّن الاسم. أضف طريقة :eat() تطبع {name} is eating. يمثّل هذا الهوية الأساسية المشتركة بين جميع الحيوانات.
  • Swimmable.lua: أنشئ خلطة تحتوي على طريقة :swim() تطبع {self.name} is swimming. هذه قدرة، وليست جميع الكائنات قادرة على السباحة، لذلك لا ينبغي أن تكون جزءًا من سلسلة الوراثة.
  • Bird.lua: أنشئ فئة Bird ترث من Animal. يجب أن يستدعي المُنشئ :new(name, canSwim) مُنشئ الفئة الأب ويخزّن ما إذا كان هذا الطائر قادرًا على السباحة. طبّق خلطة Swimmable على فئة Bird. أضف طريقة :chirp() تطبع {name} chirps!. هذا سلوك خاص بالطيور.
  • main.lua: اكتب هنا الدالة المساعدة applyMixin. اقرأ مُدخلين لاسم الطائر وما إذا كان قادرًا على السباحة (yes أو no). أنشئ نسخة من Bird، ثم اعرض قدراتها: استدعِ :eat() (الموروثة من Animal)، واستدعِ :chirp() (طريقتها الخاصة في Bird)، واستدعِ :swim() فقط إذا كان الطائر قادرًا على السباحة.

ستتلقى مُدخلين:

  1. اسم الطائر (سلسلة نصية)
  2. ما إذا كان الطائر قادرًا على السباحة: yes أو no

إذا كان الطائر قادرًا على السباحة، فينبغي أن يكون الناتج:

{name} is eating
{name} chirps!
{name} is swimming

إذا لم يكن الطائر قادرًا على السباحة، فينبغي أن يكون الناتج:

{name} is eating
{name} chirps!

على سبيل المثال، إذا كان المُدخلان هما Duck وyes، فينبغي أن يكون الناتج:

Duck is eating
Duck chirps!
Duck is swimming

إذا كان المُدخلان هما Sparrow وno، فينبغي أن يكون الناتج:

Sparrow is eating
Sparrow chirps!

يوضّح هذا التحدي الفرق الأساسي: Bird هو Animal (وراثة)، لكن السباحة قدرة اختيارية (خلطة). تُطبَّق الخلطة على الفئة، لكن منطقك في الملف الرئيسي يقرّر ما إذا كان سيستخدمها استنادًا إلى قدرات الطائر الفردية!

جرّب بنفسك

-- main.lua: نقطة الدخول - إنشاء طائر وإظهار قدراته

-- دالة مساعدة لتطبيق mixin على class
local function applyMixin(class, mixin)
    -- TODO: انسخ جميع الـ methods من الـ mixin إلى الـ class
    
end

-- طبّق الـ Swimmable mixin على Bird قبل require لـ Bird
-- Note: قد تحتاج إلى التعامل مع هذا في Bird.lua أو هنا

local Bird = require('Bird')
local Swimmable = require('Swimmable')

-- طبّق الـ mixin على class الـ Bird
applyMixin(Bird, Swimmable)

-- اقرأ المدخلات
local name = io.read()
local canSwimInput = io.read()

-- TODO: حدد ما إذا كان الطائر يستطيع السباحة بناءً على المدخل ("yes" أو "no")

-- TODO: أنشئ كائن Bird بالاسم وقدرة السباحة

-- TODO: استدعِ eat() - موروثة من Animal

-- TODO: استدعِ chirp() - method الخاصة بـ Bird

-- TODO: استدعِ swim() فقط إذا كان الطائر يستطيع السباحة
quiz iconاختبر نفسك

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

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

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