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

نسخ مستقلة

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

يعد أحد الجوانب الحاسمة في البرمجة كائنية التوجه هو أن كل مثيل (instance) يحتفظ بحالته المنفصلة الخاصة به. فعندما تقوم بإنشاء كائنين من نفس الفئة (class)، فإنهما يكونان مستقلين تماماً—تغيير أحدهما لا يؤثر على الآخر.

تأمل هذا المثال:

local Counter = {}
Counter.__index = Counter

function Counter:new(start)
    local instance = {}
    setmetatable(instance, self)
    instance.value = start or 0
    return instance
end

function Counter:increment()
    self.value = self.value + 1
end

-- إنشاء عدادين منفصلين
local counterA = Counter:new(10)
local counterB = Counter:new(5)

counterA:increment()
counterA:increment()

print(counterA.value)  -- المخرجات: 12
print(counterB.value)  -- المخرجات: 5

على الرغم من أن كلا العدادين يأتيان من نفس الفئة Counter، فإن زيادة counterA ليس لها أي تأثير على counterB. كل كائن له حقل value الخاص به والمخزن في جدول المثيل (instance table) الخاص به.

هذا الاستقلال هو ما يجعل الكائنات مفيدة. يمكنك إنشاء العشرات من اللاعبين في لعبة ما، حيث يتتبع كل منهم صحته ونتيجته الخاصة. يمكنك إدارة حسابات بنكية متعددة، لكل منها رصيد مختلف.

تحدد الفئة (class) الهيكل والسلوك، ولكن كل نسخة (instance) تعيش حياتها الخاصة ببياناتها الخاصة.

challenge icon

التحدي

سهل

دعنا نثبت أن الكائنات (objects) من نفس الفئة (class) تعيش حقاً حياة مستقلة! ستقوم ببناء فئة Wallet وإنشاء مثيلين (instances) منفصلين للمحفظة، ثم تعديلهما بشكل مستقل لإثبات أن التغييرات في أحدهما لا تؤثر على الآخر.

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

  • Wallet.lua: قم بتعريف فئة Wallet الخاصة بك باستخدام نمط المنشئ (constructor) القياسي. يجب أن تتبع كل محفظة رصيدها الخاص balance. قم بتضمين:
    • منشئ :new(startingBalance) يقوم بتهيئة المحفظة بالمبلغ المعطى
    • طريقة :add(amount) تزيد الرصيد
    • طريقة :spend(amount) تنقص الرصيد
  • main.lua: اطلب وحدة Wallet الخاصة بك وقم بإنشاء مثيلين منفصلين للمحفظة. قم بإجراء عمليات مختلفة على كل منهما لإظهار أنهما يحافظان على حالة مستقلة.

ستتلقى أربعة مدخلات:

  1. رصيد البداية للمحفظة A
  2. رصيد البداية للمحفظة B
  3. المبلغ المراد إضافته إلى المحفظة A
  4. المبلغ المراد إنفاقه من المحفظة B

في ملفك الرئيسي:

  1. قم بإنشاء walletA برصيد البداية الأول
  2. قم بإنشاء walletB برصيد البداية الثاني
  3. أضف المبلغ المحدد إلى walletA
  4. أنفق المبلغ المحدد من walletB
  5. اطبع كلا الرصيدين في سطرين منفصلين

اطبع الأرصدة النهائية بهذا التنسيق الدقيق:

Wallet A: [balance]
Wallet B: [balance]

على سبيل المثال، إذا كانت المدخلات هي 100، و 50، و 25، و 10، فيجب أن يكون المخرج:

Wallet A: 125
Wallet B: 40

لاحظ كيف أن الإضافة إلى المحفظة A لا تغير المحفظة B، والإنفاق من المحفظة B لا يؤثر على المحفظة A — فكل مثيل يحافظ على رصيده المنفصل.

ورقة مرجعية

يحتفظ كل مثيل من الفئة بحالته المنفصلة الخاصة به. يؤدي إنشاء كائنات متعددة من نفس الفئة إلى الحصول على مثيلات مستقلة تمامًا—تعديل أحدها لا يؤثر على الآخرين.

مثال يوضح استقلالية المثيلات:

local Counter = {}
Counter.__index = Counter

function Counter:new(start)
    local instance = {}
    setmetatable(instance, self)
    instance.value = start or 0
    return instance
end

function Counter:increment()
    self.value = self.value + 1
end

-- إنشاء عدادين منفصلين
local counterA = Counter:new(10)
local counterB = Counter:new(5)

counterA:increment()
counterA:increment()

print(counterA.value)  -- المخرجات: 12
print(counterB.value)  -- المخرجات: 5

لكل كائن جدول مثيل خاص به يخزن بياناته الخاصة. تحدد الفئة الهيكل والسلوك، لكن كل مثيل يحافظ على حالة مستقلة.

جرّب بنفسك

-- استدعاء وحدة المحفظة (Wallet)
local Wallet = require('Wallet')

-- قراءة المدخلات
local startingA = tonumber(io.read())
local startingB = tonumber(io.read())
local addAmount = tonumber(io.read())
local spendAmount = tonumber(io.read())

-- TODO: إنشاء walletA برصيد البداية الأول

-- TODO: إنشاء walletB برصيد البداية الثاني

-- TODO: إضافة المبلغ المحدد إلى walletA

-- TODO: خصم المبلغ المحدد من walletB

-- TODO: طباعة الأرصدة النهائية بالتنسيق المطلوب
-- التنسيق: "Wallet A: [balance]" و "Wallet B: [balance]"
quiz iconاختبر نفسك

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

جميع دروس Object Oriented Programming