Les langages / Lua / Metatables
Métatables - Orienté Objet
Les métatables permettent d'implémenter la programmation orientée objet en Lua. On peut créer des classes, des méthodes, de l'héritage et de l'encapsulation.
Créer une classe simple
-- Définir la classe Animal
local Animal = {}
Animal.__index = Animal
-- Constructeur
function Animal.new(nom, age)
local self = setmetatable({}, Animal)
self.nom = nom
self.age = age
return self
end
-- Méthodes
function Animal:sePresenter()
print("Je suis " .. self.nom .. ", j'ai " .. self.age .. " ans")
end
function Animal:vieillir()
self.age = self.age + 1
end
-- Utilisation
local chat = Animal.new("Miaou", 3)
chat:sePresenter() -- Je suis Miaou, j'ai 3 ans
chat:vieillir()
print(chat.age) -- 4
Héritage de classes
-- Classe de base
local Animal = {}
Animal.__index = Animal
function Animal.new(nom)
local self = setmetatable({}, Animal)
self.nom = nom
return self
end
function Animal:parler()
print(self.nom .. " fait du bruit")
end
-- Classe dérivée: Chien
local Chien = setmetatable({}, {__index = Animal})
Chien.__index = Chien
function Chien.new(nom, race)
local self = Animal.new(nom)
setmetatable(self, Chien)
self.race = race
return self
end
-- Surcharger une méthode
function Chien:parler()
print(self.nom .. " aboie: Woof!")
end
local rex = Chien.new("Rex", "Labrador")
rex:parler() -- Rex aboie: Woof!
Propriétés privées
-- Encapsulation avec closure
local function creerCompte(soldeInitial)
-- Variable privée
local solde = soldeInitial or 0
-- Objet public
local compte = {}
-- Méthodes publiques
function compte.deposer(montant)
if montant > 0 then
solde = solde + montant
return true
end
return false
end
function compte.retirer(montant)
if montant > 0 and montant <= solde then
solde = solde - montant
return true
end
return false
end
function compte.consulter()
return solde
end
return compte
end
local monCompte = creerCompte(100)
monCompte.deposer(50)
print(monCompte.consulter()) -- 150
-- print(monCompte.solde) -- nil (privé!)
Classe avec propriétés calculées
-- Rectangle avec aire calculée
local Rectangle = {}
Rectangle.__index = Rectangle
function Rectangle.new(largeur, hauteur)
local self = setmetatable({}, Rectangle)
self.largeur = largeur
self.hauteur = hauteur
return self
end
-- Propriété calculée via __index
function Rectangle.__index(t, key)
if key == "aire" then
return t.largeur * t.hauteur
elseif key == "perimetre" then
return 2 * (t.largeur + t.hauteur)
end
return Rectangle[key]
end
local rect = Rectangle.new(5, 10)
print(rect.aire) -- 50 (calculé)
print(rect.perimetre) -- 30 (calculé)
rect.largeur = 8
print(rect.aire) -- 80 (recalculé!)
1 exercice pour cette lecon
Les exercices demandent un compte : il faut bien enregistrer votre progression quelque part. La lecture, elle, reste libre. Creer un compte
- POO simple - Constructeur difficile 35 XP