代码之家  ›  专栏  ›  技术社区  ›  Panda Pajama

如何访问同一“类”的单独实例的“私有成员”?

lua
  •  1
  • Panda Pajama  · 技术社区  · 7 年前

    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 都是本地的 新项目 ,从每个“方法”中捕获,并且实际上是“类”的“私有成员”。

    现在,为了保持树的一致性,我创建了这个函数 添加子对象 ,它将添加传递的参数(该参数应为使用创建的另一个对象) 新项目 )添加到此对象的子对象列表,并将子对象的父对象设置为此对象。

    在C++、C语言和java中,我有“私有成员”的概念,并且可以访问同一类的不同实例。然而,在lua中,这些局部变量对于 新项目

    我想有一种方法来实现“访问同一类的单独实例的私有成员”的抽象,或者做其他事情,因此父链接和子链接只能通过导出的“方法”进行修改,这些方法可以被证明是正确的。

    我认为我想做的事情在lua是不可能的,除了 putting _parent inside of _self (therefore making it "public"), and asking pretty please for nobody else to touch it ,如果我没有弄错的话,这就是Python如何处理这个问题。

    然而,可能有一种我没有想到的方法来实现这一点,也许用另一种方法来抽象“类”的概念。有人知道如何在lua中实现“访问同一类的单独实例的私有成员”的抽象吗?

    1 回复  |  直到 7 年前
        1
  •  1
  •   Egor Skriptunoff    7 年前
    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)