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



Modified text is an extract of the original Stack Overflow Documentation
Sous licence CC BY-SA 3.0
Non affilié à Stack Overflow