وراثت (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() صدا زده می‌شود، لوا به‌ترتیب جستجو می‌کند:

  1. خود شیء pup
  2. کلاس Puppy (از طریق __index)
  3. کلاس Dog (از طریق __index Puppy)
  4. کلاس Animal

اولین مورد پیدا شده استفاده می‌شود — این همان زنجیره ارث‌بری است!

این مبحث بخشی از دوره آموزش کامل لوا است.

ابزارهای مرتبط