サーチ…
前書き
ルア自身はクラスシステムを提供していません。しかし、クラスやオブジェクトをほんの数回のトリックでテーブルとして実装することは可能です。
構文
function <class>.new() return setmetatable({}, {__index=<class>}) end
単純なオブジェクトオリエンテーション
ここでは、非常に単純なクラスシステムの基本的な例を示します
Class = {}
local __instance = {__index=Class} -- Metatable for instances
function Class.new()
local instance = {}
setmetatable(instance, __instance)
return instance
-- equivalent to: return setmetatable({}, __instance)
end
変数やメソッドを追加するには、それらをクラスに追加するだけです。どちらのインスタンスも、すべてのインスタンスでオーバーライドできます。
Class.x = 0
Class.y = 0
Class:getPosition()
return {self.x, self.y}
end
クラスのインスタンスを作成するには:
object = Class.new()
または
setmetatable(Class, {__call = Class.new}
-- Allow the class itself to be called like a function
object = Class()
それを使うには:
object.x = 20
-- This adds the variable x to the object without changing the x of
-- the class or any other instance. Now that the object has an x, it
-- will override the x that is inherited from the class
print(object.x)
-- This prints 20 as one would expect.
print(object.y)
-- Object has no member y, therefore the metatable redirects to the
-- class table, which has y=0; therefore this prints 0
object:getPosition() -- returns {20, 0}
オブジェクトのメタメソッドの変更
持つ
local Class = {}
Class.__meta = {__index=Class}
function Class.new() return setmetatable({}, Class.__meta)
object = Class.new()
を使用して単一のインスタンスobject = Class.new()
の動作を変更したいと仮定して、
回避すべきいくつかの間違いがあります:
setmetatable(object, {__call = table.concat}) -- WRONG
これは、古いmetatableを新しいものと交換するので、クラスの継承を破る
getmetatable(object).__call = table.concat -- WRONG AGAIN
テーブルの「値」は参照のみであることに注意してください。実際には、コンストラクタが1で定義されていない限り、オブジェクトのすべてのインスタンスの実際のテーブルは1つだけです。このようにすることで、クラスのすべてのインスタンスの動作が変更されます。
これを行う1つの正しい方法:
クラスを変更することなく:
setmetatable(
object,
setmetatable(
{__call=table.concat},
{__index=getmetatable(object)}
)
)
これはどのように作動しますか? - 間違った#1のような新しいメタテーブルを作成しますが、空のままにする代わりに、元のメタテーブルへのソフトコピーを作成します。あたかもそれがクラスインスタンスそのものであるかのように、元のものから新しいメタ可能な "継承"と言うことができます。元のメタテーブルの値を変更せずにオーバーライドできるようになりました。
クラスを変更する:
1位(推奨):
local __instance_meta = {__index = Class.__meta}
-- metatable for the metatable
-- As you can see, lua can get very meta very fast
function Class.new()
return setmetatable({}, setmetatable({}, __instance_meta))
end
2位(推奨されない): 1
1 function Class.new() return setmetatable({}, {__index=Class}) end