сейчас мы продолжим рассматривать метатаблици в Lua и для начала как я обещал(не помню обещал или нет, а смотреть в статью лень ) объяснить зачем эта строка Код object = {} object.__index = object это сделано для того чтобы невозможно было бы обратится к екземпляру объекта как к таблице. так как я плохо объясняю я буду решать задачи и показывать как это делал. задача 1. создать объект с атрибутами mapName mapXSize mapYSize создать в объекте методы: newMap устанавливает все значения в карте на определённое setMapElem задаёт определённой ячейке карты определённое значение getMapElem возвращает значение определённой ячейки карты copyMap копировать карту из одного объекта в другой freeMap очистить карту поставить на 0 а не nil invertMap инвертировать карту Код object = {} object.__index = object function newObject(name, xs, ys) a = {} a.mapName = name a.mapXSize = xs a.mapYSize = ys a.map = {} --создание карты, обычный двойной цикл для 2-мерного массива for i = 0, xs - 1 do a.map[i] = {} for j = 0, ys - 1 do a.map[i][j] = 0 end end a.newMap = function(value) --тоже самое что и немного выше, только в место 0 стоит value for i = 0, xs - 1 do self.map[i] = {} for j = 0, ys - 1 do self.map[i][j] = value end end end a.setMapElem(x, y, value) -- думаю объяснять не надо self.map[x][y] = value end a.getMapElem(x, y) -- аналогично return self.map[x][y] end a.copyMap(obj) -- в двойном цикле все элементы копируются по одному -- а почему не obj.map = self.map? -- да потому что - в Lua типы данных ссылочные -- вписав obj.map = self.map то после этого -- оба объекта будут иметь ссылку на один массив -- а это значит что если изменится один то и второй тоже! -- именно мы копируем по значению с каждого элемента for i = 0, #self.map do for j = 0, #self.map[i] do obj.map[i][j] = self.map[i][j] end end end a.freeMap = function() -- тоже самое что и newMap но вместо value стоит 0 for i = 0, xs - 1 do self.map[i] = {} for j = 0, ys - 1 do self.map[i][j] = 0 end end end a.invertMap = function() for i = 0, xs - 1 do self.map[i] = {} for j = 0, ys - 1 do -- если елемент равняется нули или false то он будет равен 1 if self.map[i][j] == 0 or self.map[i][j] == false then self.map[i][j] = 1 else self.map[i][j] = 0 end end end end для начала это всё. тема будет обновятся. здесь всё написано правильно если выдаст ошибку то это скорее всего несовместимость версий спасибо за внимание =)
тема была обновлена.
сейчас мы будем изучать методы и наследие
Код Object = {} Object.text = "gg" -- атрибут объекта Object - text Object.set = function(value) self.text = value end Object.get = function() retirn self.text end
-- создадим экземпляр объекта Object local object = {} setmetatable(object, Object) object.get() --> nil -- почему nil? -- потому что переменные - атрибуты не передаются тогда давайте заново создадим экземпляр objetc = {} setmetatable(object, {__index = Object}) object.get() --> gg -- что мы сделали? -- мы присвоили атрибуту __index саму таблицу -- ранее я говорил что это не дает обращаться к ней как к таблице -- так и есть но только частично -- когда мы запрашиваем атрибут начинается поиск в экземпляре объекта -- если его там нет то поиск переходит к __index -- если __index функция то она вызывается -- а если это таблица то поиск начинается в ней -- то есть в object начинается поиск атрибута text -- но его там нет далее поиск переходит к __index поскольку это таблица -- поиск начинается в ней в главном объекте Object есть этот атрибут он и возвращается
теперь поговорим про наследование
наследование это когда объект наследует другой объект и имеет все его атрибуты и методы например объект зверь его наследует объект черепаха - то есть черепаха имеет все атрибуты объект зверь сердце, мозг, конечности, вены, кровь ... но и при этом имеет свои собственные - панцирь, клюв, длинная шея ...
сейчас мы создадим объект Child который будет наследовать объект Main
Код Main = {} Main.__index = Main Main.lifes = 0 Main.getl = function()return self.lifes end Child = {} Child.__index = Child setmetatable(Child, Main) -- заставляем Child наследовать Main someobject = {} setmetatble(someobject, Child) -- создаём экземпляр объекта Child print(someobject.getl())--> выведет 0 а не nil -- в этом случае если поиск не нашел в экземпляре lifes переходит к поиску в главном объекте экземпляра Child -- но если и там не нашло то поиск начинается уже в объекте Main
ну это всё, да.
|