Как получить доступ к «частному члену» отдельного экземпляра того же «класса»? - PullRequest
0 голосов
/ 22 декабря 2018

Смежный вопрос: как реализованы защищенные элементы при использовании подхода замыкания к ООП? .Скорее всего, проблема та же, хотя абстракция, которую я пытаюсь реализовать, отличается.


В настоящее время я реализую древовидную структуру для представления графа сцены в 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, поэтому они не являются частью экспортируемого объекта, поэтому я не могу получить к ним доступ.

Я хотел бы получить способреализовать эту абстракцию «доступа к закрытым членам отдельного экземпляра того же класса» или сделать что-то еще, чтобы ссылки на родительские и дочерние объекты могли изменяться только с помощью экспортированных «методов», которые могут быть проверены на правильность.

IЯ думаю, что то, что я хочу сделать, просто невозможно в lua, если не считать , помещая _parent внутри _self (и, следовательно, сделать его "публичным"), и просить, чтобы никто другой не трогал его То есть, если я не ошибаюсь, как Python справляется с этим.

Однако, возможно, есть способ достичь этого, о котором я не думал, возможно, используя другой способ абстрагирования концепции"учебный класс".Кто-нибудь знает, как реализовать абстракцию «доступа к закрытым членам отдельного экземпляра того же класса» в lua?

1 Ответ

0 голосов
/ 22 декабря 2018
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)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...