サーチ…


前書き

ルア自身はクラスシステムを提供していません。しかし、クラスやオブジェクトをほんの数回のトリックでテーブルとして実装することは可能です。

構文

  • 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



Modified text is an extract of the original Stack Overflow Documentation
ライセンスを受けた CC BY-SA 3.0
所属していない Stack Overflow