Related question: how do implemented protected members when using the closure approach to OOP?。尽管我尝试实现的抽象是不同的,但问题很可能是相同的。
我目前正在实现一个树结构来表示lua中的场景图。为此,lua有几种抽象类概念的方法,而我正在使用这种方法:
new_item = function()
local _self = {}
local _parent = nil
local _children = {}
_self.add_child = function(child)
-- add child to _children
table.insert(_children, child) -- no problems here
-- set child's _parent to _self
child._parent = _self -- this doesn't work: "child._parent" doesn't even exist
end
return _self
end
a = new_item()
b = new_item()
a.add_child(b)
new_item
返回的对象是一个表,其中包含一个名为add_child
的项目,这是我定义的功能。局部变量_self
,_parent
和_children
在new_item
的范围内是局部的,是从每个“方法”中捕获的,并且实际上是“类”的“私有成员” “。
现在,为了保持树的一致性,我正在创建此函数add_child
,它将把传递的参数(预期是用new_item
创建的另一个对象)添加到以下子项的列表中此对象,并将孩子的父母设为该对象。
在C ++,C#和Java中,我有“私有成员”的概念,并且可以访问同一类的不同实例的成员。但是在lua中,这些局部变量是new_item
范围内的局部变量,因此它们不是导出对象的一部分,因此我无法访问它们。
我想有一种方法来实现这种“访问同一类的单独实例的私有成员”的抽象,或者执行其他操作,因此父级和子级链接只能通过导出的“方法”来修改。被证明是正确的。
我认为我想做的只是在lua中是不可能的,缺少putting _parent
inside of _self
(therefore making it "public"), and asking pretty please for nobody else to touch it,如果我没记错的话,那就是Python如何处理这个问题。
但是,可能有一种我没有想到的方法可以实现,也许可以使用另一种方式来抽象“类”的概念。有人知道如何在lua中实现“访问同一类的单独实例的私有成员”的抽象吗?
答案 0 :(得分:1)
function create_class()
local class = {}
-- when object is garbage-collected, its private data will be auto-removed
local private_data_of_all_objects = setmetatable({}, {__mode = "k"})
function class.create_new_object()
local object = {}
local private = {} -- private fields of this object
private.children = {}
private.parent = nil
private_data_of_all_objects[object] = private
function object.add_child(child)
table.insert(private.children, child)
private_data_of_all_objects[child].parent = object
end
return object
end
return class
end
cl = create_class()
a = cl.create_new_object()
b = cl.create_new_object()
a.add_child(b)