Classes via les métatables
Simulez des classes avec des tables et __index pour rechercher les méthodes.
Classes via les métatables est une leçon Lua Academy gratuite sur CoddyKit. Ceci est la leçon 1 sur 4. Tu peux lire la leçon complète ci-dessous gratuitement — puis la pratiquer en direct dans le navigateur avec un éditeur de code intégré et un tuteur IA 24/7. Elle fait partie du parcours d'apprentissage Lua Academy, et ta progression se synchronise sur le web et l'application CoddyKit. Le cours Lua Academy comprend 4 leçons au total.
Schéma de table de classe
En Lua, une « classe » est simplement une table qui stocke des méthodes. Les instances sont des tables dont la métatable contient __index pointant vers la table de classe. Ainsi, toutes les méthodes sont accessibles sur les instances grâce à la chaîne de recherche.
local Animal = {}
Animal.__index = Animal
function Animal.new(name, sound)
return setmetatable({name=name, sound=sound}, Animal)
end
function Animal:speak()
print(self.name .. " says " .. self.sound)
end
local dog = Animal.new("Rex","Woof")
dog:speak() -- Rex says Woof__index pointe vers la classe
Définir ClassName.__index = ClassName signifie « rechercher les clés absentes dans la table de classe ». Lorsqu’une méthode d’instance est appelée, Lua ne la trouve pas dans l’instance, consulte la métatable (__index), trouve la classe, puis y recherche la méthode.
local Point = {}
Point.__index = Point
Point.type = "2D Point"
function Point.new(x,y)
return setmetatable({x=x,y=y}, Point)
end
function Point:magnitude()
return math.sqrt(self.x^2 + self.y^2)
end
local p = Point.new(3,4)
print(p:magnitude()) -- 5.0
print(p.type) -- 2D Point (from class)Schéma du constructeur
La fonction new() est le constructeur : elle crée une table contenant les données de l’instance et la renvoie enveloppée dans une métatable pointant vers la classe. C’est la manière standard de créer des objets en Lua.
local Circle = {}
Circle.__index = Circle
function Circle.new(cx, cy, radius)
assert(radius > 0, "radius must be positive")
return setmetatable({cx=cx, cy=cy, r=radius}, Circle)
end
function Circle:area()
return math.pi * self.r^2
end
function Circle:perimeter()
return 2 * math.pi * self.r
end
local c = Circle.new(0, 0, 5)
print(string.format("Area: %.2f", c:area()))Syntaxe des méthodes et des fonctions
obj:method() est une forme abrégée de obj.method(obj). Définissez les méthodes avec la syntaxe utilisant deux-points (function Cls:method()) pour obtenir implicitement self. Appelez-les avec deux-points pour transmettre l’instance. Mélanger le point et les deux-points provoque des erreurs difficiles à détecter.
local Dog = {}
Dog.__index = Dog
-- Define with colon: self is implicit
function Dog:bark(times)
for i = 1, (times or 1) do
print(self.name .. ": Woof!")
end
end
function Dog.new(name)
return setmetatable({name=name}, Dog)
end
local d = Dog.new("Buddy")
d:bark(2) -- Buddy: Woof! (x2)
-- Dog.bark(d,1) -- same thing, explicit selfChamps de classe et champs d’instance
Les champs de la table de classe sont partagés par toutes les instances (ce sont des variables de classe). Les champs de la table d’instance sont propres à chaque instance. Une instance peut masquer un champ de classe en créant son propre champ portant le même nom.
local Entity = {}
Entity.__index = Entity
Entity.count = 0 -- class-level counter
function Entity.new(name)
Entity.count = Entity.count + 1
return setmetatable({name=name, id=Entity.count}, Entity)
end
local a = Entity.new("alpha")
local b = Entity.new("beta")
local c = Entity.new("gamma")
print(Entity.count) -- 3
print(a.id, b.id, c.id) -- 1 2 3tostring pour les classes
Ajoutez __tostring à la table de classe pour obtenir une sortie d’affichage lisible. Comme la métatable de l’instance est la classe et que la classe possède __tostring, toutes les instances l’utiliseront automatiquement.
local Vec2 = {}
Vec2.__index = Vec2
Vec2.__tostring = function(v)
return string.format("Vec2(%g, %g)", v.x, v.y)
end
function Vec2.new(x,y)
return setmetatable({x=x,y=y}, Vec2)
end
function Vec2.__add(a, b)
return Vec2.new(a.x+b.x, a.y+b.y)
end
local v1 = Vec2.new(1,2)
local v2 = Vec2.new(3,4)
print(v1+v2) -- Vec2(4, 6)Vérifier le type d’une instance
Vérifiez si un objet est une instance d’une classe en comparant sa métatable à la table de classe. C’est l’équivalent Lua de instanceof.
local Dog = {}
Dog.__index = Dog
function Dog.new(name)
return setmetatable({name=name}, Dog)
end
local function isDog(obj)
return getmetatable(obj) == Dog
end
local d = Dog.new("Rex")
local t = {}
print(isDog(d)) -- true
print(isDog(t)) -- falseMéthodes privées
Les méthodes privées sont des fonctions locales dans le fichier du module. Elles ne peuvent pas être appelées depuis l’extérieur, mais sont accessibles depuis les méthodes publiques du module en tant que valeurs capturées.
local Account = {}
Account.__index = Account
-- Private helper
local function validate(amount)
return type(amount)=="number" and amount > 0
end
function Account.new(balance)
return setmetatable({balance=balance or 0}, Account)
end
function Account:deposit(amount)
assert(validate(amount), "invalid amount")
self.balance = self.balance + amount
end
function Account:getBalance() return self.balance endComparer des classes
Surchargez __eq et __lt pour personnaliser l’égalité et l’ordre. Lua n’appelle __eq pour les tables que lorsque les deux opérandes partagent la même métatable.
local Temp = {}
Temp.__index = Temp
Temp.__eq = function(a,b) return a.celsius == b.celsius end
Temp.__lt = function(a,b) return a.celsius < b.celsius end
Temp.__tostring = function(t)
return t.celsius.."°C"
end
function Temp.new(c)
return setmetatable({celsius=c}, Temp)
end
local t1 = Temp.new(100)
local t2 = Temp.new(0)
print(t1 == Temp.new(100)) -- true
print(t2 < t1) -- truePlusieurs classes
Chaque classe est une table indépendante dotée de sa propre métatable. Les objets de classes différentes possèdent des métatables différentes. C’est le fondement d’un système de POO à plusieurs classes en Lua.
local Cat = {}
Cat.__index = Cat
function Cat.new(name) return setmetatable({name=name,lives=9},Cat) end
function Cat:loseLife() self.lives=self.lives-1; return self.lives end
local Dog2 = {}
Dog2.__index = Dog2
function Dog2.new(name) return setmetatable({name=name,tricks={}},Dog2) end
function Dog2:learn(t) self.tricks[#self.tricks+1]=t end
local c = Cat.new("Whiskers")
local d = Dog2.new("Buddy")
d:learn("sit"); d:learn("stay")
print(c:loseLife(), #d.tricks) -- 8 2Vérification rapide
Pourquoi définissons-nous ClassName.__index = ClassName ?
Récapitulatif : classes via les métatables
Résumé :
- Classe = table +
__index = self - Constructeur :
function Cls.new(...) return setmetatable({}, Cls) end - Méthodes : définies sur la table de classe et appelées avec la syntaxe utilisant deux-points
- Champs de classe et d’instance : les champs de classe sont partagés, ceux des instances sont propres à chaque objet
- Vérification du type :
getmetatable(obj) == Cls
Questions Fréquemment Posées
La leçon « Classes via les métatables » est-elle gratuite ?
Oui — le texte complet de « Classes via les métatables » est gratuit à lire ici sur le web. Pour la pratiquer de manière interactive (un éditeur de code intégré et un tuteur IA 24/7) et déverrouiller le reste du cours Lua Academy, passe à CoddyKit PRO. Le cours Lua Academy comprend 4 leçons au total.
Qu'est-ce que j'apprendrai dans « Classes via les métatables » ?
Simulez des classes avec des tables et __index pour rechercher les méthodes. Tu pratiques Lua Academy avec du code pratique que tu exécutes directement dans le navigateur, et un tuteur IA 24/7 répond à tes questions au fur et à mesure que tu avances dans la leçon.
Dois-je avoir de l'expérience pour commencer Lua Academy ?
Aucune expérience préalable n'est requise. Lua Academy sur CoddyKit est structuré pour les débutants jusqu'aux apprenants avancés, donc tu peux commencer ici ou depuis le début et avancer à ton rythme. Ceci est la leçon 1 sur 4.
Combien de temps prend la leçon « Classes via les métatables » ?
La plupart des leçons CoddyKit prennent environ 5–10 minutes. Chacune est courte et interactive, tu progresses régulièrement et tu repiques exactement où tu t'es arrêté sur le web et l'app.
Peux-tu écrire et exécuter du code dans cette leçon Lua Academy ?
Oui. Chaque leçon Lua Academy inclut un éditeur de code intégré, tu écris et exécutes du vrai code directement dans ton navigateur et tu reçois des retours IA instantanés — aucune configuration locale requise.
Toutes les leçons de ce cours
- Classes via les métatables
- Constructeurs et new()
- Méthodes d’instance et self
- Encapsulation avec des fermetures