Приведенный выше код не очень выразителен для создания экземпляров классов, поскольку используемый конструктор не имеет аргументов.В результате все 3 экземпляра идентичны.Кроме того, «Monster.monster_1» и аналогичные НЕ являются экземплярами, они являются nils.
Чтобы увидеть что-то более интересное, я подготовил следующий пример кода:
-- Default properties values
local Monster = {
name = "orc",
health = 10,
attack = 3
}
-- constructor
function Monster:Create(instance_name)
-- take defaults from self (that is Monster table)
instance_name = instance_name or self.name
return {
name = instance_name,
health = self.health,
attack = self.attack,
WarCry = function(this)
print(this.name .. ": GRAAAHH!!!")
end
}
end
monster_1 = Monster:Create()
monster_2 = Monster:Create("named")
--monster_2 = Monster.Create() -- Incorrect use!
--monster_3 = Monster.Create(monster_3) -- Incorrect use!
print(monster_1.name) -- orc
print(type(monster_1)) -- table
print(monster_2.name) -- named
print(type(monster_2)) -- table
monster_1:WarCry() -- orc: GRAAAHH!!!
monster_2:WarCry() -- named: GRAAAHH!!!
Теперь конструктор имеетявный аргумент («имя_экземпляра») и неявный (таблица монстров).Последнее необходимо для использования ключевого слова "self".Поэтому мы не должны использовать точечный синтаксис при создании экземпляров, это приведет к ошибке.Если мы избегаем «self» в определении конструктора, мы можем использовать точечный синтаксис без ошибок, как вы можете видеть ниже:
-- constructor
function Monster:Create(instance_name)
-- take defaults from self (that is Monster table)
instance_name = instance_name or Monster.name
return {
name = instance_name,
health = Monster.health,
attack = Monster.attack,
WarCry = function(this)
print(this.name .. ": GRAAAHH!!!")
end
}
end
monster_1 = Monster:Create()
monster_2 = Monster.Create(nil, "named")
Обратите внимание на «nil» в последнем вызове.Этот аргумент обязателен, потому что конструктор был определен синтаксисом двоеточия, но мы используем точечный вызов.Если мы опускаем аргумент "nil", значение "named" будет рассматриваться как родительская таблица в контексте двоеточия.
ADDED:
Мы также можем создать конструктор, используя синтаксис точки:
Monster.CreateByDot = function(instance_name)
instance_name = instance_name or 'Noname';
return {
name = instance_name,
WarCry = function(this)
print(this.name .. ": GRAAAHH!!!")
end
}
end
monster_3 = Monster.CreateByDot()
monster_4 = Monster.CreateByDot('Fourth')
monster_3:WarCry() -- Noname: GRAAAHH!!!
monster_4:WarCry() -- Fourth: GRAAAHH!!!
и посмотрите аргумент "имя_экземпляра" в действии.