Пример в PiL откровенно запутанный.Он описывает то, что называется наследование прототипа .Это означает, что нет никакого различия между классами и объектами.Вот версия вашего new
метода, которая немного более правильна:
function Class:new()
-- Note that self refers to the class, here. We have to return a new object.
self.__index = self
local o = {a=1}
setmetatable(o, self)
return o
end
Но у нас все еще есть проблема: поскольку наш конструктор устанавливает переменную экземпляра, мы не можем использовать ее для создания подклассов.Если мы попробуем, у всех этих подклассов будет a
, установленный внутри себя, а не в их экземплярах.Мы могли бы определить init
метод, который мы должны вызывать каждый раз, когда создаем новый экземпляр, но это было бы больно.Вот один из возможных способов разделения классов и объектов:
-- Make sure every class has an __index pointing to itself. This lets it be the
-- metatable for both instances and subclasses.
local Class = {}
Class.__index = Class
function Class:new()
local o = {a=1}
setmetatable(o, self)
return o
end
function Class:incr()
self.a = 2 * self.a
return self
end
-- To inherit, simply use Class as the metatable.
local Subclass = {}
Subclass.__index = Subclass
setmetatable(Subclass, Class)
Таким образом, new
используется только для создания экземпляров.