Aller au contenu principal
ShadowAcademy

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