Lua
Object-Oriëntatie
Zoeken…
Invoering
Lua zelf biedt geen klassensysteem. Het is echter mogelijk om klassen en objecten als tabellen te implementeren met slechts een paar trucs.
Syntaxis
function <class>.new() return setmetatable({}, {__index=<class>}) end
Eenvoudige objectoriëntatie
Hier is een eenvoudig voorbeeld van hoe u een zeer eenvoudig klassensysteem kunt uitvoeren
Class = {}
local __instance = {__index=Class} -- Metatable for instances
function Class.new()
local instance = {}
setmetatable(instance, __instance)
return instance
-- equivalent to: return setmetatable({}, __instance)
end
Om variabelen en / of methoden toe te voegen, voegt u ze gewoon toe aan de klasse. Beide kunnen voor elke instantie worden opgeheven.
Class.x = 0
Class.y = 0
Class:getPosition()
return {self.x, self.y}
end
En om een instantie van de klasse te maken:
object = Class.new()
of
setmetatable(Class, {__call = Class.new}
-- Allow the class itself to be called like a function
object = Class()
En om het te gebruiken:
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}
Metamethoden van een object veranderen
Het hebben van
local Class = {}
Class.__meta = {__index=Class}
function Class.new() return setmetatable({}, Class.__meta)
Ervan uitgaande dat we het gedrag van een object = Class.new()
één exemplaar object = Class.new()
met een metatable,
er zijn een paar fouten te vermijden:
setmetatable(object, {__call = table.concat}) -- WRONG
Hiermee wordt de oude metatabel vervangen door de nieuwe, waardoor de klasse-overerving wordt verbroken
getmetatable(object).__call = table.concat -- WRONG AGAIN
Houd er rekening mee dat de tabel "waarden" slechts een referentie zijn; er is in feite slechts één tabel voor alle instanties van een object, tenzij de constructor is gedefinieerd als in 1 , dus door dit te doen wijzigen we het gedrag van alle instanties van de klasse.
Een juiste manier om dit te doen:
Zonder de klasse te veranderen:
setmetatable(
object,
setmetatable(
{__call=table.concat},
{__index=getmetatable(object)}
)
)
Hoe werkt dit? - We maken een nieuwe metatabel zoals in fout # 1, maar in plaats van deze leeg te laten, maken we een zachte kopie naar de originele metatabel. Je zou kunnen zeggen dat de nieuwe metatable van de originele 'erft' alsof het een klasse-instantie zelf is. We kunnen nu de waarden van de oorspronkelijke metatabel overschrijven zonder ze te wijzigen.
De klasse wijzigen:
1e (aanbevolen):
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
2e (minder aanbevolen): zie 1
1 function Class.new() return setmetatable({}, {__index=Class}) end