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

الخصائص المحسوبة

جزء من قسم Object Oriented Programming في رحلة Lua على Coddy — الدرس 15 من 70.

توفر أدوات الجلب (Getters) والتعيين (Setters) إمكانية الوصول إلى القيم المخزنة، ولكن في بعض الأحيان تحتاج إلى بيانات لا توجد كحقل مخزن—بل يجب حسابها من سمات أخرى. تُسمى هذه الخصائص المحسوبة.

فكر في مستطيل. أنت تقوم بتخزين عرضه وارتفاعه، لكن المساحة لا يتم تخزينها في أي مكان - بل يتم حسابها بضرب هاتين القيمتين معاً. وبدلاً من تخزين بيانات زائدة، يمكنك إنشاء دالة (method) تقوم بحساب النتيجة وإرجاعها:

local Rectangle = {}
Rectangle.__index = Rectangle

function Rectangle:new(width, height)
    local instance = {}
    setmetatable(instance, self)
    instance.width = width
    instance.height = height
    return instance
end

function Rectangle:getArea()
    return self.width * self.height
end

لا تقوم طريقة :getArea() بإرجاع قيمة مخزنة—بل تقوم بحساب المساحة من جديد في كل مرة تستدعيها فيها. يتميز هذا النهج بميزة رئيسية: إذا تغير العرض أو الارتفاع، تعكس المساحة الأبعاد الجديدة تلقائيًا دون الحاجة إلى تحديث أي شيء.

local box = Rectangle:new(5, 3)
print(box:getArea())  -- الناتج: 15

box.width = 10
print(box:getArea())  -- الناتج: 30

تحافظ الخصائص المحسوبة (Calculated properties) على اتساق كائناتك. فبدلاً من تخزين القيم التي تعتمد على حقول أخرى (والمخاطرة بأن تصبح قديمة)، يمكنك حسابها عند الطلب. ينطبق هذا النمط على أي بيانات مشتقة—مثل المحيطات، أو المتوسطات، أو السلاسل النصية المنسقة، أو أي قيمة يمكن تحديدها من السمات الموجودة.

challenge icon

التحدي

سهل

لنقم ببناء فئة Box تقوم بحساب حجمها عند الطلب! بدلاً من تخزين الحجم كحقل، ستقوم بإنشاء خاصية محسوبة تحسبه من أبعاد الصندوق كلما دعت الحاجة.

ستقوم بتنظيم الكود الخاص بك عبر ملفين:

  • Box.lua: قم بتعريف فئة Box الخاصة بك باستخدام نمط النموذج الأولي (prototype pattern) القياسي. يخزن كل صندوق ثلاثة أبعاد: width، و height، و depth. قم بتضمين:
    • منشئ :new(width, height, depth) يقوم بتخزين الأبعاد الثلاثة جميعها
    • طريقة :getVolume() تقوم بحساب وإرجاع الحجم (width × height × depth)
    • طريقة :getSurfaceArea() تقوم بحساب وإرجاع إجمالي مساحة السطح
  • main.lua: قم باستدعاء وحدة Box الخاصة بك، وأنشئ مثيلاً (instance) للصندوق، ووضح كيف تعكس الخصائص المحسوبة الأبعاد الحالية تلقائيًا.

يتم حساب مساحة سطح الصندوق كالتالي: 2 × (width×height + height×depth + width×depth)

ستتلقى ثلاثة مدخلات تمثل أبعاد الصندوق:

  1. العرض (Width)
  2. الارتفاع (Height)
  3. العمق (Depth)

في ملفك الرئيسي، أنشئ صندوقًا بالأبعاد المعطاة، ثم اطبع سطرين:

  1. الحجم باستخدام :getVolume()
  2. مساحة السطح باستخدام :getSurfaceArea()

على سبيل المثال، إذا كانت المدخلات هي 3، و 4، و 5، يجب أن يكون المخرج:

60
94

جمال الخصائص المحسوبة هو أنها تظل دقيقة دائمًا. إذا قمت لاحقًا بتغيير أحد أبعاد الصندوق، فإن استدعاء :getVolume() مرة أخرى سيعيد القيمة الجديدة الصحيحة تلقائيًا — دون الحاجة إلى تحديثات يدوية!

ورقة مرجعية

الخصائص المحسوبة هي دوال تقوم بحساب وإرجاع قيم بناءً على سمات أخرى بدلاً من تخزينها مباشرة. يضمن ذلك اتساق البيانات ويزيل التكرار.

مثال على خاصية محسوبة للمساحة:

local Rectangle = {}
Rectangle.__index = Rectangle

function Rectangle:new(width, height)
    local instance = {}
    setmetatable(instance, self)
    instance.width = width
    instance.height = height
    return instance
end

function Rectangle:getArea()
    return self.width * self.height
end

تقوم الدالة :getArea() بحساب المساحة في كل مرة يتم استدعاؤها، مما يعكس تلقائياً أي تغييرات تطرأ على العرض أو الارتفاع:

local box = Rectangle:new(5, 3)
print(box:getArea())  -- المخرجات: 15

box.width = 10
print(box:getArea())  -- المخرجات: 30

الخصائص المحسوبة مفيدة لأي بيانات مشتقة مثل المحيطات، أو الأحجام، أو المتوسطات، أو السلاسل النصية المنسقة التي يمكن تحديدها من السمات الموجودة.

جرّب بنفسك

-- استدعاء وحدة Box
local Box = require('Box')

-- قراءة أبعاد المدخلات
local width = tonumber(io.read())
local height = tonumber(io.read())
local depth = tonumber(io.read())

-- TODO: إنشاء مثيل للصندوق بالأبعاد المعطاة

-- TODO: طباعة الحجم باستخدام ()getVolume:

-- TODO: طباعة مساحة السطح باستخدام ()getSurfaceArea:
quiz iconاختبر نفسك

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

جميع دروس Object Oriented Programming