Love2D: ООП в LUA

Руководство по Lua 5.1
Итак, первое, что нам нужно узнать - ООП в Lua НЕТ!
Но не отчаивайтесь: синтаксических сахар данного языка позволяет создать некое подобие функционалу ООП.
Для начала создадим обычную таблицу (базовый класс):
Base = {}
Теперь добавим в нашу таблицу поле field:
Base.field = "text"
Создадим две функции для работы с данным полем:
function Base:setField(value)
    self.field = value
end

function Base:getField()
    return self.field
end
Обратите внимание! Если перед именем метода вместо обычной точки стоит двоеточие - первым параметром в метод будет передаваться self, то есть сам объект класса (аналог this в С++)
Итак, базовый класс создан. Это шаблон, по которому должны создаваться объекты данного типа.
Создадим объект типа Base:
local base = {}				--как видно, это обычная таблица
Теперь установим для этой таблицы метатаблицу:
setmetatable(base, {__index = Base})
Теперь самая обычная таблица стала объектом типа Base. "Как?" - спросите вы. Для этого подробнее разберём принцип работы оператора __index.
При вызове функции сначала осуществляется поиск в указанной таблице. Если в ней нет нужного функции, то в метатаблице ищется метод index. Если index является функцией, вызывается эта функция. Если __index - таблица, то поиск функции осуществляется в этой таблице.
То есть теперь можно теперь из нашего объекта типа Base можно вызывать функции "базового класса":
print(base:getField())				--> "text"
Сначала происходит поиск метода getField в таблице base. Ничего не найдено. Далее в таблице base ищется метатаблица а в ней ищется поле index. Найдено. Поле index является таблицей. В таблице __index (а это на самом деле ссылка на таблицу Base) ищется поле getField. Найдено. Эта функция и вызывается. Поскольку при вызове функции мы использовали двоеточие base:getField(), то в функцию getField первым параметром передается таблица base.
Давайте изменим значение этого поля field:
base:setField('Xtreme Game Making')
print(base:getField())				 --> "Xtreme Game Making"

Теперь поговорим о имитации наследования.
По сути наследование в данном случае выполняется так же как и создание объекта типа Base:
Child = {}
setmetatable(Child, {__index = Base})
Давайте переопределим в Child метод getField():
function Child:getField()
    return 'some new string'
end
Теперь создадим объект типа Child:
local child = {}
setmetatable(child, {__index = Child})
print(child:getField())				--> "some new string"
А как же быть, если мы хотим вызвать для child метод родительского класса? Всё очень просто:
child:setField('string of the Base class')
print(Base.getField(child))				--> "string of the Base class"

Просмотров: 1 995

Андреич #1 - 4 года назад 0
заметочка. не забыть дополнить статью информацией из официальной документации...