0Pricing
Lua Academy · Урок

Проектирование базового класса и конструктора

Спроектируйте фабрику 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 — локальная установка не требуется.

Все уроки этого курса

  1. Проектирование базового класса и конструктора
  2. Многоуровневое наследование
  3. Композиция примесей и проверка интерфейсов
  4. instanceof и изучение типов
← Назад к Lua Academy