0Pricing
Lua Academy · Leçon

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 self

Champs 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  3

tostring 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))  -- false

Mé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 end

Comparer 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)              -- true

Plusieurs 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  2

Vé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

  1. Classes via les métatables
  2. Constructeurs et new()
  3. Méthodes d’instance et self
  4. Encapsulation avec des fermetures
← Retour à Lua Academy