Lua
Objektorientierung
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