Suche…


Einführung

Lua selbst bietet kein Klassensystem an. Es ist jedoch möglich, Klassen und Objekte mit wenigen Tricks als Tabellen zu implementieren.

Syntax

  • function <class>.new() return setmetatable({}, {__index=<class>}) end

Einfache Objektorientierung

Hier ist ein einfaches Beispiel für ein sehr einfaches Klassensystem

Class = {}
local __instance = {__index=Class} -- Metatable for instances
function Class.new()
    local instance = {}
    setmetatable(instance, __instance)
    return instance
-- equivalent to: return setmetatable({}, __instance)
end

Um Variablen und / oder Methoden hinzuzufügen, fügen Sie sie einfach zur Klasse hinzu. Beide können für jede Instanz überschrieben werden.

Class.x = 0
Class.y = 0
Class:getPosition()
    return {self.x, self.y}
end

Und um eine Instanz der Klasse zu erstellen:

object = Class.new()

oder

setmetatable(Class, {__call = Class.new}
    -- Allow the class itself to be called like a function
object = Class()

Und um es zu benutzen:

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}

Metaverfahren eines Objekts ändern

Haben

local Class = {}
Class.__meta = {__index=Class}
function Class.new() return setmetatable({}, Class.__meta)

Angenommen, wir möchten das Verhalten einer einzelnen Instanz object = Class.new() mit einer Metabelle ändern,

Es sind einige Fehler zu vermeiden:

setmetatable(object, {__call = table.concat}) -- WRONG

Dadurch wird das alte Metable mit dem neuen ausgetauscht, wodurch die Klassenvererbung gebrochen wird

getmetatable(object).__call = table.concat -- WRONG AGAIN

Beachten Sie, dass Tabellenwerte nur als Referenz dienen. Tatsächlich gibt es nur eine tatsächliche Tabelle für alle Instanzen eines Objekts, sofern der Konstruktor nicht als 1 definiert ist. Dadurch ändern wir das Verhalten aller Instanzen der Klasse.


Ein richtiger Weg, dies zu tun:

Ohne die Klasse zu wechseln:

setmetatable(
    object,
    setmetatable(
        {__call=table.concat},
        {__index=getmetatable(object)}
    )
)

Wie funktioniert das? - Wir erstellen eine neue Metabelle wie in Fehler # 1, aber anstatt sie leer zu lassen, erstellen wir eine Soft-Kopie der ursprünglichen Metabelle. Man könnte sagen, dass das neue metatable von der ursprünglichen "erbt", als wäre es selbst eine Klasseninstanz. Wir können jetzt Werte der ursprünglichen Metable überschreiben, ohne sie zu ändern.

Klasse wechseln:

1. (empfohlen):

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. (weniger empfohlen): siehe 1


1 function Class.new() return setmetatable({}, {__index=Class}) end



Modified text is an extract of the original Stack Overflow Documentation
Lizenziert unter CC BY-SA 3.0
Nicht angeschlossen an Stack Overflow