Méthodes d’instance et self
Définissez des méthodes avec la syntaxe utilisant deux-points et le paramètre self implicite.
Méthodes d’instance et self est une leçon Lua Academy gratuite sur CoddyKit. Ceci est la leçon 3 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.
self est l'instance
Lorsque vous appelez obj:method(), Lua transmet automatiquement obj comme premier argument. Par convention, ce paramètre est nommé self. Grâce à self, la méthode accède aux données de l'instance et appelle d'autres méthodes.
local Counter = {}
Counter.__index = Counter
function Counter.new(start)
return setmetatable({value=start or 0, step=1}, Counter)
end
function Counter:increment()
self.value = self.value + self.step
end
function Counter:getValue() return self.value end
local c = Counter.new(10)
c:increment(); c:increment()
print(c:getValue()) -- 12Enchaînement des méthodes
Renvoyez self depuis les méthodes pour permettre l'enchaînement : obj:method1():method2():method3(). Chaque appel renvoie le même objet, ce qui permet un style fluide. Cette technique convient particulièrement aux méthodes qui modifient l'état.
local Builder = {}
Builder.__index = Builder
function Builder.new()
return setmetatable({parts={}},Builder)
end
function Builder:add(s) self.parts[#self.parts+1]=s; return self end
function Builder:addAll(t)
for _,v in ipairs(t) do self.parts[#self.parts+1]=v end
return self
end
function Builder:build() return table.concat(self.parts," ") end
local result = Builder.new()
:add("Hello")
:add("from")
:addAll({"Lua","OOP"})
:build()
print(result) -- Hello from Lua OOPAppel d'autres méthodes
Les méthodes peuvent appeler d'autres méthodes sur la même instance via self:otherMethod(). Cela favorise la réutilisation du code au sein d'une classe. Les assistants privés peuvent être de simples fonctions locales qui reçoivent explicitement self.
local Stack = {}
Stack.__index = Stack
function Stack.new() return setmetatable({_data={},_size=0},Stack) end
function Stack:push(v) self._size=self._size+1; self._data[self._size]=v end
function Stack:pop()
if self:isEmpty() then return nil end
local v=self._data[self._size]; self._data[self._size]=nil
self._size=self._size-1; return v
end
function Stack:peek()
return not self:isEmpty() and self._data[self._size] or nil
end
function Stack:isEmpty() return self._size==0 end
function Stack:size() return self._size end
local s=Stack.new(); s:push(1);s:push(2);s:push(3)
print(s:pop(),s:peek(),s:size()) -- 3 2 2Attention à la redéfinition d'une méthode
Définir dans une instance un champ portant le même nom qu'une méthode de classe masque cette méthode pour cette instance. Il s'agit généralement d'un bogue : soyez prudent lorsque les noms des champs d'instance peuvent entrer en conflit avec ceux des méthodes.
local Dog = {}
Dog.__index = Dog
function Dog.new(n) return setmetatable({name=n},Dog) end
function Dog:speak() print(self.name..": Woof!") end
local d = Dog.new("Rex")
d:speak() -- Rex: Woof!
-- Accidental shadow:
d.speak = "loud" -- now d.speak is a string, not a function
local ok,err = pcall(function() d:speak() end)
print(ok, err) -- false attempt to call a string valueself dans les fonctions de rappel
Passer une méthode comme fonction de rappel fait perdre le self implicite. Encapsulez la méthode dans une fermeture pour capturer self.
local Timer = {}
Timer.__index = Timer
function Timer.new(n) return setmetatable({count=n},Timer) end
function Timer:tick()
self.count=self.count-1
print("Ticking, count:", self.count)
end
local t = Timer.new(3)
-- Wrong: loses self
-- local cb = t.tick -- cb(t) works but cb() doesn't
-- Correct: closure captures self
local cb = function() t:tick() end
cb(); cb(); cb() -- Ticking 3 timesMéthodes statiques et méthodes d'instance
Une méthode statique est appelée sur la classe, et non sur une instance. Elle ne possède pas de self (ou reçoit la classe comme self). En Lua, il n'existe pas de distinction formelle : par convention, utilisez . (et non :) pour les méthodes statiques.
local MathUtils = {}
MathUtils.__index = MathUtils
-- Static method (no instance needed)
function MathUtils.clamp(v, lo, hi)
return math.max(lo, math.min(hi, v))
end
-- Instance method (needs self)
function MathUtils:scale(factor)
self.value = self.value * factor
end
print(MathUtils.clamp(15, 0, 10)) -- 10
local m = setmetatable({value=5},MathUtils)
m:scale(3)
print(m.value) -- 15Méthodes de mixin
Ajoutez les méthodes d'une table de mixin à une classe sans héritage formel. Il s'agit d'une composition à plat : copiez ou référencez les fonctions du mixin dans la table de la classe.
local Serializable = {}
function Serializable:serialize()
local parts={}
for k,v in pairs(self) do
if type(v)~="function" then
parts[#parts+1]=k.."="..tostring(v)
end
end
return "{"..table.concat(parts,",").."}"
end
local User = {}
User.__index = User
User.serialize = Serializable.serialize -- mixin!
function User.new(n,a) return setmetatable({name=n,age=a},User) end
local u = User.new("Alice",30)
print(u:serialize())Méthodes abstraites
Lua n'impose pas les méthodes abstraites, mais vous pouvez définir dans une classe de base une méthode qui déclenche une erreur, obligeant les sous-classes à la redéfinir. C'est une convention indiquant qu'une méthode « doit être redéfinie ».
local Shape = {}
Shape.__index = Shape
function Shape.new() return setmetatable({},Shape) end
function Shape:area()
error(type(self).." must implement area()",2)
end
function Shape:describe()
print("Shape area:", self:area())
end
local sq={}
setmetatable(sq,{__index=Shape})
function sq:area() return 4*4 end
sq:describe() -- Shape area: 16Tables de méthodes
Pour les classes qui possèdent de nombreuses méthodes, organisez-les en groupes par fonctionnalité. Toutes les méthodes d'une même table utilisent la même recherche dans la métatable, mais vous pouvez les répartir par responsabilité au moyen de sous-espaces de noms.
local Entity = {}
Entity.__index = Entity
Entity.Physics = {}
function Entity.Physics:applyForce(fx,fy)
self.vx=(self.vx or 0)+fx
self.vy=(self.vy or 0)+fy
end
Entity.Render = {}
function Entity.Render:draw()
print(string.format("Draw at (%g,%g)",self.x or 0,self.y or 0))
end
-- Mix into main class
for k,v in pairs(Entity.Physics) do Entity[k]=v end
for k,v in pairs(Entity.Render) do Entity[k]=v end
function Entity.new(x,y) return setmetatable({x=x,y=y},Entity) end
local e=Entity.new(10,20); e:draw(); e:applyForce(5,0); print(e.vx)Délégation ou héritage
Préférez la délégation (conserver une référence) aux longues chaînes d'héritage. Une classe peut déléguer à un autre objet au lieu d'en hériter, ce qui limite le couplage et permet à chaque classe de rester ciblée.
local Logger = {}
Logger.__index = Logger
function Logger.new(name) return setmetatable({name=name},Logger) end
function Logger:log(msg) print("["..self.name.."] "..msg) end
local Service = {}
Service.__index = Service
function Service.new(name)
return setmetatable({
name=name,
logger=Logger.new(name) -- delegation
},Service)
end
function Service:start()
self.logger:log("starting...") -- delegate logging
print(self.name, "running")
end
Service.new("AuthService"):start()Vérification rapide
Quelle est la différence entre obj:method() et obj.method() ?
Récapitulatif : méthodes d'instance
Résumé :
- Syntaxe d'appel avec deux-points :
obj:method()==obj.method(obj) - Renvoyez self pour enchaîner les méthodes
- Appelez d'autres méthodes :
self:otherMethod() - Fonctions de rappel : encapsulez-les dans une fermeture pour préserver self
- Méthodes statiques : utilisez la notation avec un point par convention
- Préférez la délégation à l'héritage profond pour plus de souplesse
Questions Fréquemment Posées
La leçon « Méthodes d’instance et self » est-elle gratuite ?
Oui — le texte complet de « Méthodes d’instance et self » 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 « Méthodes d’instance et self » ?
Définissez des méthodes avec la syntaxe utilisant deux-points et le paramètre self implicite. 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 3 sur 4.
Combien de temps prend la leçon « Méthodes d’instance et self » ?
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