现在,我在Lua中使用closures for implementing OOP。下面是一个简短的示例。尝试在stronger_heal中实现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文件中定义的全局私有(private)变量或私有(private)变量。如何保护只有infested_mariner才能访问的成员,并且解决方案不涉及将所有派生类与父类放在同一个文件中?

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

最佳答案

在Lua中,您只能访问它们范围内的局部变量。为了允许其他函数查看您的变量,您将需要对其进行重写,以使 protected 变量位于子类可以访问的表中。

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

如果要使用真正的 protected 变量,则需要将表分为公共(public)和 protected 东西。一种方法是更改​​祝福功能,以使其接收以下两个表:

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

如何进行设置,以使构造函数彼此之间传递 protected 表,这是一个练习。如果您走这条路线,您可能希望有一些功能可以帮您完成,这样您就不会有机会每天接触 protected table 。

关于oop - 在使用面向对象操作的封闭方法时,如何实现 protected 成员?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/16758925/

10-10 21:25
查看更多