کلاسها و اشیاء در لوا
ساخت کلاس با جدول و متاجدول، سازنده (new)، متدها و self
شیگرایی در لوا
لوا کلمه کلیدی class ندارد — اما با جدولها و متاجدولها میتوان شیگرایی کامل پیاده کرد! این الگو در جامعه لوا استاندارد است.
ساخت یک کلاس
-- تعریف کلاس
local Dog = {}
Dog.__index = Dog -- مهم! جستجوی متدها
-- سازنده (constructor)
function Dog.new(name, breed)
local self = setmetatable({}, Dog)
self.name = name
self.breed = breed
return self
end
-- متد
function Dog:bark()
return self.name .. " هاپ هاپ!"
end
function Dog:introduce()
return "من " .. self.name .. " هستم، نژاد " .. self.breed
end
-- استفاده
local rex = Dog.new("رکس", "ژرمن")
print(rex:bark()) -- رکس هاپ هاپ!
print(rex:introduce()) -- من رکس هستم، نژاد ژرمن
دو نکته کلیدی
Dog.__index = Dog— وقتی کلیدی در شیء نباشد، در خود کلاس جستجو میشود (متدها اینجا هستند)function Dog:bark()— دونقطه یعنی پارامتر مخفیselfاضافه میشود
دونقطه در برابر نقطه
-- این دو کاملاً معادلند:
function Dog:bark()
return self.name .. " هاپ!"
end
function Dog.bark(self)
return self.name .. " هاپ!"
end
-- و در فراخوانی:
rex:bark() -- معادل:
rex.bark(rex) -- self خودکار پاس میشود
اشتباه رایج: فراخوانی با نقطه و فراموشی self —
rex.bark() خطا میدهد چون self پاس نشده!مثال کامل: کلاس حساب بانکی
local Account = {}
Account.__index = Account
function Account.new(owner, balance)
return setmetatable({
owner = owner,
balance = balance or 0
}, Account)
end
function Account:deposit(amount)
self.balance = self.balance + amount
return self.balance
end
function Account:withdraw(amount)
if amount > self.balance then
return nil, "موجودی کافی نیست!"
end
self.balance = self.balance - amount
return self.balance
end
function Account:getInfo()
return string.format("%s: %.0f تومان", self.owner, self.balance)
end
-- استفاده
local acc = Account.new("علی", 100000)
acc:deposit(50000)
print(acc:getInfo()) -- علی: 150000 تومان
local ok, err = acc:withdraw(999999)
if not ok then print(err) end -- موجودی کافی نیست!
هر شیء مستقل است
local a1 = Account.new("علی", 100)
local a2 = Account.new("مریم", 200)
a1:deposit(50)
print(a1.balance) -- 150
print(a2.balance) -- 200 (دستنخورده!)
__tostring برای کلاس
function Account:__tostring()
return "حساب[" .. self.owner .. "]: " .. self.balance
end
-- حالا print مستقیم کار میکند
print(a1) -- حساب[علی]: 150
الگوی کلاس لوا را حفظ کنید: جدول + __index + new + متدهای دونقطه. این الگو در همه پروژههای لوا (از Roblox تا Neovim) یکسان است!
این مبحث بخشی از دوره آموزش کامل لوا است.