6

现在我正在使用闭包在 Lua中实现 OOP 。下面是一个精简的例子。我的问题发生在尝试实现stronger_healinside时infested_mariner

--------------------
-- 'mariner module':
--------------------
mariner = {}

-- Global private variables:
local idcounter = 0
local defaultmaxhp = 200
local defaultshield = 10  

function mariner.new ()
   local self = {}

   -- Private variables:  
   local hp = maxhp        

   -- Public methods:

   function self.sethp (newhp)
      hp = math.min (maxhp, newhp)
   end
   function self.gethp ()
      return hp
   end
   function self.setarmorclass (value)
      armorclass = value
      updatearmor ()
   end


   return self
end

-----------------------------
-- 'infested_mariner' module:
-----------------------------

-- Polymorphism sample

infested_mariner = {}

function infested_mariner.bless (self)

   -- New methods:
   function self.strongerheal (value)
     -- how to access hp here?
     hp = hp + value*2  
   end      

   return self
end

function infested_mariner.new ()
   return infested_mariner.bless (mariner.new ())
end

如果我将我的infested_mariner定义放在另一个 .lua 文件中,它将无法访问全局私有变量,或访问在基本 .lua 文件中定义的私有变量。我如何拥有只能infested_mariner访问的受保护成员,并且解决方案不涉及将所有派生类与父类放在同一个文件中?

注意:我目前在子类中使用 getter 和 setter。

4

2 回答 2

2

这是封闭方法的局限性。没有办法hp从封闭外部访问。

这是一个意识形态问题......有人说受保护的成员会破坏封装,所以应该避免:将所有数据设为私有并在需要时扩展接口(添加公共功能)。这么说的人往往喜欢关闭方法。

如果你想使用受保护的成员,我可能不会使用闭包方法。一个好的命名约定可能是最简单的事情。

self.public_thing = "asdf"
self._protected_thing = "asdf"

当然,数据实际上是公开的,但这种方法效果很好。这几乎就是 Python 所做的。当你想弄乱内部结构时,它会派上用场,比如测试。

于 2013-07-19T18:53:32.910 回答
1

在 Lua 中,您只能访问其范围内的局部变量。为了允许其他函数查看您的变量,您需要重写它,以便受保护的变量位于子类可访问的表中。

一种方法是在当前类中创建公共属性并使用命名约定(如以下划线开头的名称)来表示受保护的内容。您可能知道这一点,但我不得不说,我认为这种方法通常真正的受保护变量更容易实现。

如果您想要真正的受保护变量,则需要将公共表和受保护表分开。一种方法是更改​​ bless 函数,使其接收这两个表:

function infested_mariner.bless (pub, pro)
   -- New methods:
   function pub.strongerheal (value)
     pro.hp = pro.hp + value*2
   end
   return pub
end

如何进行设置以使构造函数将受保护的表传递给彼此是一个练习。如果你走这条路,你可能希望有一些功能为你做这件事,这样你就没有机会每天接触受保护的桌子。

于 2013-05-26T15:44:49.067 回答