Итоги
В этом уроке вы узнали, что:
- Таблица может хранить функции рядом с данными. Такая таблица — объект.
function farm.describe(f) … end— сокращение отfarm.describe = function(f) … end.stringиmath— тоже таблицы с функциями. - Двоеточие передаёт сам объект:
crop:grow()— сокращение отcrop.grow(crop), аfunction crop:grow()— отfunction crop.grow(self). Внутри такого методаself— это объект, у которого его вызвали. Точка вместо двоеточия при вызове даётattempt to index a nil value (local 'self'). - Конструктор — это функция, которая создаёт объект и возвращает его. Без
returnвы получитеnil:attempt to index a nil value (local 'carrot'). setmetatable(t, mt)даёт таблице метатаблицу. Её__indexговорит, где искать ключи, которых нет уt. Так объекты делят методы и так строка находитstring.upperдляs:upper().- Класс — это таблица, которая хранит методы и служит метатаблицей своих экземпляров:
local Crop = {},Crop.__index = Crop, конструкторCrop.new, который вызываетsetmetatable(crop, Crop), и методы вродеfunction Crop:grow(). БезCrop.__index = Cropвы получитеattempt to call a nil value (method 'grow'). - Метаметоды позволяют объектам работать с остальным Lua:
__tostring— сprintиtostring(но не с..),__eq— с==,__lt— с<,>иtable.sort,__le— с<=и>=, а__add— с+. - Один класс наследует от другого через
setmetatable(Tree, {__index = Crop}). Его конструктор вызывает конструктор родителя, а затемsetmetatable(tree, Tree). Метод с тем же именем переопределяет родительский, аCrop.describe(self)вызывает родительскую версию. Метаметоды не наследуются.
После этого урока вас ждёт последний небольшой проект — реестр животных Эммы, где пригодятся и строки, и объекты. А затем, в уроке «Корутины», вы напишете функции, которые умеют останавливаться посередине и продолжать позже, например для персонажа, который делает по одному делу в день.
Но сначала соберите этот урок воедино. Эмма торгует на рынке, а программа в редакторе использует класс Product, которого ещё нет, поэтому она завершается с ошибкой attempt to index a nil value (global 'Product').
Задание
- 1
Над
stallнапишите классProduct. Его конструкторProduct.new(name, price, count)создаёт товар с этими тремя ключами, а__tostringописывает его так, как показано ниже. Программа выводит:Тыква: осталось 3, цена: 20 Морковь: осталось 10, цена: 5 Клубника: осталось 6, цена: 12 - 2
Добавьте метод
Product:sell(amount). Он продаётamountштук, но не больше, чем осталось, и возвращает монеты, которые Эмма получает за них. Под циклом продайте 2 тыквы и 15 морковок (их осталось только 10), сложите монеты и выведите их:Монеты: 90 - 3
Вечером Эмма хочет посмотреть, что осталось, начиная с самого дешёвого. Добавьте в
Productметаметод__lt, который сравнивает цены, отсортируйте прилавок черезtable.sortи выведите его ещё раз. Программа заканчивается так:Монеты: 90 Морковь: осталось 0, цена: 5 Клубника: осталось 6, цена: 12 Тыква: осталось 1, цена: 20