Проектирование базового класса и конструктора
Спроектируйте фабрику Class(), настраивающую метатаблицы и конструкторы new().
«Проектирование базового класса и конструктора» — бесплатный урок Lua Academy на CoddyKit. Это урок 1 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Lua Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Lua Academy содержит 4 уроков всего.
Цель: многоразовая фабрика классов
Нам нужна функция Class(), возвращающая новый объект класса с корректным конструктором, поиском методов и объектно-ориентированной семантикой.
Каркас фабрики классов
Фабрика создаёт таблицу класса с метатаблицей для вызова методов.
local function Class()
local cls = {}
cls.__index = cls
cls.__name = "AnonymousClass"
function cls:new(...)
local instance = setmetatable({}, cls)
if instance.init then instance:init(...) end
return instance
end
return cls
endОпределение класса
Создайте класс, определите init (конструктор) и добавьте методы.
local Animal = Class()
Animal.__name = "Animal"
function Animal:init(name, sound)
self.name = name
self.sound = sound
end
function Animal:speak()
print(self.name .. " says " .. self.sound)
end
local cat = Animal:new("Cat", "Meow")
cat:speak() -- Cat says MeowШаблон конструктора
Конструктор :new(...) создаёт экземпляр с помощью setmetatable({}, cls), а затем вызывает :init(...) для инициализации. Это отделяет выделение памяти от инициализации.
Имя класса для отладки
Сохраните cls.__name и определите __tostring, чтобы экземпляры выводились в понятном виде.
function Animal:__tostring()
return "<" .. Animal.__name .. ": " .. self.name .. ">"
end
print(tostring(cat)) -- <Animal: Cat>Значения по умолчанию в init
Задавайте значения по умолчанию в init с помощью or.
function Vehicle:init(opts)
self.speed = opts.speed or 0
self.fuel = opts.fuel or 100
self.engine = opts.engine or "petrol"
endМетоды класса и методы экземпляра
Методы, определённые с помощью function cls.method(), являются методами класса (без self). Методы, определённые с помощью function cls:method(), получают экземпляр в качестве self.
Статические свойства
Свойства, заданные непосредственно в таблице класса, общие для всех экземпляров, если только их не переопределяют поля экземпляра.
Animal.count = 0
function Animal:init(name, sound)
Animal.count = Animal.count + 1
self.name = name; self.sound = sound
end
print(Animal.count) -- 0
Animal:new("Dog","Woof")
print(Animal.count) -- 1Конструктор копирования
Метод :clone() создаёт копию экземпляра, поверхностно копируя его поля.
function Animal:clone()
local copy = setmetatable({}, getmetatable(self))
for k, v in pairs(self) do copy[k] = v end
return copy
endМетаметод сравнения
Определите __eq для осмысленного сравнения экземпляров.
Animal.__eq = function(a, b)
return a.name == b.name
endПочему не rawget
Используйте self.field, а не rawget, чтобы разрешить доступ к полям через метаметоды в производных классах. Используйте rawget только тогда, когда явно необходимо обойти это поведение.
Вопрос о проектировании конструктора
Почему init вызывается отдельно от функции выделения памяти new?
Повторение: базовый класс и конструктор
Фабрика Class() создаёт таблицу как класс, задаёт __index = cls для поиска методов и предоставляет :new() вместе с :init(). Это основа всех объектно-ориентированных шаблонов Lua.
Часто задаваемые вопросы
Урок «Проектирование базового класса и конструктора» бесплатный?
Да — полный текст урока «Проектирование базового класса и конструктора» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Lua Academy, подпишись на CoddyKit PRO. Курс Lua Academy содержит 4 уроков всего.
Чему я научусь в уроке «Проектирование базового класса и конструктора»?
Спроектируйте фабрику Class(), настраивающую метатаблицы и конструкторы new(). Ты практикуешь Lua Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать Lua Academy?
Предыдущий опыт не требуется. Lua Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 1 из 4.
Сколько времени занимает урок «Проектирование базового класса и конструктора»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке Lua Academy?
Да. Каждый урок Lua Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Проектирование базового класса и конструктора
- Многоуровневое наследование
- Композиция примесей и проверка интерфейсов
- instanceof и изучение типов