6

現在、Lua で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

定義を別の .lua ファイルに配置infested_marinerすると、グローバル プライベート変数にアクセスしたり、ベース .lua ファイルで定義されたプライベート変数にアクセスしたりできなくなります。アクセスのみできる保護されたメンバーを作成するにはどうすればよいですか?infested_marinerまた、解決策には、すべての派生クラスを親と同じファイルに含める必要はありません。

注:現在、子クラスでゲッターとセッターを使用しています。

4

2 に答える 2

1

Lua では、スコープ内のローカル変数にのみアクセスできます。他の関数が変数を参照できるようにするには、変数を書き直して、保護された変数が子クラスからアクセスできるテーブルにあるようにする必要があります。

これを行う 1 つの方法は、現在のクラスでパブリック プロパティを作成し、命名規則 (アンダースコアで始まる名前など) を使用して、保護されているものを示すことです。あなたはおそらくこれを知っていますが、このアプローチは通常、実際の保護された変数よりも実装がはるかに簡単だと言わざるを得ません。

実際に保護された変数が必要な場合は、パブリックと保護されたもののテーブルを分離する必要があります。1 つの方法は、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 に答える