Многоуровневое наследование
Поддерживайте глубокие цепочки наследования с корректной передачей вызовов через __index.
«Многоуровневое наследование» — бесплатный урок Lua Academy на CoddyKit. Это урок 2 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Lua Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Lua Academy содержит 4 уроков всего.
Повторение: одиночное наследование
Одиночное наследование достигается установкой Child.__index = Parent. При поиске метода, если его нет в дочернем классе, он ищется в родительском через __index.
Расширение фабрики классов для наследования
Добавьте в базовый класс метод :extend(), который создаёт подкласс, связанный с родительским классом.
function Animal:extend()
local cls = {}
cls.__index = cls
setmetatable(cls, {__index = self})
cls.super = self
function cls:new(...)
local inst = setmetatable({}, cls)
if inst.init then inst:init(...) end
return inst
end
return cls
endСоздание подкласса
Создайте класс «Собака» как подкласс класса «Животное», переопределив init и добавив новые методы.
local Dog = Animal:extend()
function Dog:init(name)
Dog.super.init(self, name, "Woof")
self.tricks = {}
end
function Dog:learnTrick(trick)
self.tricks[#self.tricks+1] = trick
end
local d = Dog:new("Rex")
d:learnTrick("sit")
d:speak() -- Rex says WoofМногоуровневая цепочка
Расширьте класс «Собака», чтобы создать GuideDog — трёхуровневую цепочку наследования.
local GuideDog = Dog:extend()
function GuideDog:init(name, owner)
GuideDog.super.init(self, name)
self.owner = owner
end
function GuideDog:guide()
print(self.name .. " guides " .. self.owner)
endВызов методов суперкласса
Всегда вызывайте методы суперкласса через ссылку на класс, а не через self, чтобы избежать бесконечной рекурсии.
function Dog:init(name)
Dog.super.init(self, name, "Woof") -- explicit super call
endПорядок разрешения методов
Lua разрешает методы снизу вверх по цепочкам __index. Цепочка имеет вид GuideDog → Dog → Animal → nil. Побеждает первый найденный метод.
Переопределение методов
Чтобы переопределить метод, определите в подклассе метод с тем же именем. Для частичного переопределения явно вызывайте метод суперкласса.
function Dog:speak()
print(self.name .. " barks!")
Dog.super.speak(self) -- also call parent speak
endОграничения глубины
Очень глубокие цепочки наследования замедляют поиск методов: каждый уровень добавляет один шаг __index. Для цепочек глубже 3–4 уровней предпочитайте композицию.
Проверка принадлежности классу
Пройдите по цепочке метатаблиц, чтобы проверить, принадлежит ли экземпляр определённому классу.
local function isA(instance, cls)
local mt = getmetatable(instance)
while mt do
if mt == cls then return true end
mt = getmetatable(mt)
end
return false
end
print(isA(d, Dog)) -- true
print(isA(d, Animal)) -- trueГлубокое копирование с сохранением класса
При глубоком копировании экземпляров сохраняйте метатаблицу, чтобы копия оставалась экземпляром правильного класса.
Когда предпочесть композицию
Используйте наследование для настоящих отношений «является» (собака является животным). Используйте композицию (таблицы компонентов) для отношений «содержит» или гибкого объединения поведения.
Вопрос о наследовании
Как работает многоуровневое наследование в Lua?
Повторение: многоуровневое наследование
Расширьте фабрику классов методом :extend(), который выстраивает связи __index. Явно вызывайте методы суперкласса с помощью ClassName.super.method(self, ...). Проверяйте принадлежность классу, проходя по цепочке метатаблиц.
Часто задаваемые вопросы
Урок «Многоуровневое наследование» бесплатный?
Да — полный текст урока «Многоуровневое наследование» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Lua Academy, подпишись на CoddyKit PRO. Курс Lua Academy содержит 4 уроков всего.
Чему я научусь в уроке «Многоуровневое наследование»?
Поддерживайте глубокие цепочки наследования с корректной передачей вызовов через __index. Ты практикуешь Lua Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать Lua Academy?
Предыдущий опыт не требуется. Lua Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 2 из 4.
Сколько времени занимает урок «Многоуровневое наследование»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке Lua Academy?
Да. Каждый урок Lua Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Проектирование базового класса и конструктора
- Многоуровневое наследование
- Композиция примесей и проверка интерфейсов
- instanceof и изучение типов