وراثت (Inheritance) در لوا
ارثبری کلاسها با متاجدولها، فراخوانی متد والد و override
وراثت چیست؟
وراثت یعنی کلاسی از کلاس دیگر «ارث ببرد» — متدها و ویژگیهای والد را به ارث بگیرد و در صورت نیاز آنها را تغییر (override) دهد.
پیادهسازی وراثت در لوا
ترفند ساده: __index کلاس فرزند را به کلاس والد وصل میکنیم:
-- کلاس والد
local Animal = {}
Animal.__index = Animal
function Animal.new(name)
return setmetatable({name = name}, Animal)
end
function Animal:speak()
return self.name .. " صدایی میدهد"
end
function Animal:introduce()
return "من " .. self.name .. " هستم"
end
-- کلاس فرزند
local Dog = setmetatable({}, {__index = Animal})
Dog.__index = Dog
function Dog.new(name, breed)
-- ساخت از طریق والد
local self = Animal.new(name)
self.breed = breed
-- اما متاجدول را به Dog وصل میکنیم
setmetatable(self, Dog)
return self
end
-- Override: بازنویسی متد والد
function Dog:speak()
return self.name .. " هاپ هاپ!"
end
-- متد جدید مخصوص فرزند
function Dog:fetch()
return self.name .. " توپ را میآورد!"
end
-- استفاده
local generic = Animal.new("حیوان")
local rex = Dog.new("رکس", "ژرمن")
print(generic:speak()) -- حیوان صدایی میدهد
print(rex:speak()) -- رکس هاپ هاپ! (override شده)
print(rex:introduce()) -- من رکس هستم (از والد ارث برده)
print(rex:fetch()) -- متد جدید فرزند
فراخوانی متد والد (super)
لوا super ندارد، اما میتوان مستقیم متد والد را صدا زد:
function Dog:introduce()
-- اول متد والد
local parentIntro = Animal.introduce(self)
-- بعد اضافهاش کن
return parentIntro .. "، نژاد " .. self.breed
end
print(rex:introduce()) -- من رکس هستم، نژاد ژرمن
زنجیره وراثت چند سطحی
Animal (والد)
└── Dog (فرزند)
└── Puppy (نوه!)
local Puppy = setmetatable({}, {__index = Dog})
Puppy.__index = Puppy
function Puppy.new(name, breed)
local self = Dog.new(name, breed)
setmetatable(self, Puppy)
return self
end
function Puppy:speak()
return self.name .. " هی هی!"
end
local pup = Puppy.new("لاکی", "ژرمن")
print(pup:speak()) -- لاکی هی هی! (از Puppy)
print(pup:fetch()) -- از Dog (ارث)
print(pup:introduce()) -- از Animal (ارث!)
الگوی تمیز برای وراثت
-- تابع کمکی برای ساخت کلاس فرزند
local function extend(parent)
local child = setmetatable({}, {__index = parent})
child.__index = child
return child
end
local Cat = extend(Animal)
function Cat.new(name, indoor)
local self = Animal.new(name)
self.indoor = indoor
setmetatable(self, Cat)
return self
end
function Cat:speak()
return self.name .. " میو!"
end
نحوه جستجوی متد
وقتی pup:speak() صدا زده میشود، لوا بهترتیب جستجو میکند:
- خود شیء
pup - کلاس
Puppy(از طریق __index) - کلاس
Dog(از طریق __index Puppy) - کلاس
Animal
اولین مورد پیدا شده استفاده میشود — این همان زنجیره ارثبری است!
این مبحث بخشی از دوره آموزش کامل لوا است.