Lua
Orientation Objet
Recherche…
Introduction
Lua lui-même n'offre aucun système de classe. Il est cependant possible d'implémenter des classes et des objets sous forme de tableaux avec juste quelques astuces.
Syntaxe
function <class>.new() return setmetatable({}, {__index=<class>}) end
Orientation d'objet simple
Voici un exemple de base de la façon de faire un système de classe très simple
Class = {}
local __instance = {__index=Class} -- Metatable for instances
function Class.new()
local instance = {}
setmetatable(instance, __instance)
return instance
-- equivalent to: return setmetatable({}, __instance)
end
Pour ajouter des variables et / ou des méthodes, ajoutez-les simplement à la classe. Les deux peuvent être remplacés pour chaque instance.
Class.x = 0
Class.y = 0
Class:getPosition()
return {self.x, self.y}
end
Et pour créer une instance de la classe:
object = Class.new()
ou
setmetatable(Class, {__call = Class.new}
-- Allow the class itself to be called like a function
object = Class()
Et pour l'utiliser:
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}
Changer les méthodes d'un objet
Ayant
local Class = {}
Class.__meta = {__index=Class}
function Class.new() return setmetatable({}, Class.__meta)
En supposant que nous voulions changer le comportement d'un seul object = Class.new()
instance object = Class.new()
utilisant une métatable,
il y a quelques erreurs à éviter:
setmetatable(object, {__call = table.concat}) -- WRONG
Cela échange l'ancien avec le nouveau, brisant ainsi l'héritage de classe
getmetatable(object).__call = table.concat -- WRONG AGAIN
Gardez à l'esprit que les "valeurs" de la table ne sont que des références. il n'y a en fait qu'une seule table réelle pour toutes les instances d'un objet, sauf si le constructeur est défini comme dans 1 , ce qui modifie le comportement de toutes les instances de la classe.
Une façon correcte de le faire:
Sans changer de classe:
setmetatable(
object,
setmetatable(
{__call=table.concat},
{__index=getmetatable(object)}
)
)
Comment cela marche-t-il? - Nous créons une nouvelle métifiable comme dans l’erreur n ° 1, mais au lieu de la laisser vide, nous créons une copie électronique sur la métifiable originale. On pourrait dire que la nouvelle métatable "hérite" de l'original comme s'il s'agissait d'une instance de classe elle-même. Nous pouvons maintenant remplacer les valeurs de la métatable d'origine sans les modifier.
Changer la classe:
1er (recommandé):
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ème (moins recommandé): voir 1
1 function Class.new() return setmetatable({}, {__index=Class}) end