我知道在这个网站上有一些关于在Lua中实现OOP的问题,但是,这个有点不同(至少与我发现的相比)。
我正在尝试创建一个名为“ human ”的类,并使其成为使用“人类”的“新”构造函数创建的对象,继承人类内部的所有内容,除了它的构造函数。但是,我也不希望能够在人类内部使用人类内部的方法。因此,人类内部的任何东西都只传递给创建的对象。这是一个例子:
-- "Human" class
human = {}
function human.new(name)
local new = {} -- New object
-- Metatable associated with the new object
local newMeta =
{
__index = function(t, k)
local v = human[k] -- Get the value from human
print("Key: ", k)
if type(v) == "function" then -- Takes care of methods
return function(_, ...)
return v(new, ...)
end
else
return v -- Otherwise return the value as it is
end
end
}
-- Defaults
new.Name = name
new.Age = 1
return setmetatable(new, newMeta)
end
-- Methods
function human:printName()
print(self.Name)
end
function human:setAge(new)
self.Age = new
end
-- Create new human called "bob"
-- This works as expected
local bob = human.new("Bob")
print(bob.Name) -- prints 'Bob'
bob:printName() -- prints 'Bob'
bob:setAge(10) -- sets the age to 10
print(bob.Age) -- prints '10'
-- But I don't want something like this allowed:
local other = bob.new("Mike") -- I don't want the constructor passed
-- I'd also like to prevent this from being allowed, for "human" is a class, not an object.
human:printName()
因此使用human.new("Bob")
创建对象可以正常工作,但它也会传递构造函数,我仍然可以在类上使用对象方法。我对OOP的概念很新,所以如果这是一个可怕的问题,我很抱歉。但如果有人能提供帮助,我会很感激。
答案 0 :(得分:4)
之前我遇到过同样的问题。你需要两张桌子。一个用于对象方法,一个用于类方法。将构造对象的元表设置为对象方法表。例如:
local Class = {}
local Object = {}
Object.__index = Object
function Class.new()
return setmetatable({}, Object)
end
setmetatable(Class, {__call = Class.new})
function Object.do()
...
end
return Class
并使用它
Class = require('Class')
local obj = Class.new() -- this is valid
obj.do() -- this is valid
obj.new() -- this is invalid
Class.do() -- this is invalid