Variables d'instance
Fait partie de la section Object Oriented Programming du Journey Lua de Coddy — leçon 12 sur 70.
Bienvenue dans un nouveau chapitre consacré à la manière dont les objets gèrent leurs données internes. Vous avez appris à créer des classes et des instances — il est maintenant temps d'explorer comment chaque instance stocke et gère son propre état unique.
Les variables d'instance sont des champs qui appartiennent exclusivement à un seul objet. Lorsque vous assignez une valeur à self.something à l'intérieur d'une méthode ou d'un constructeur, ces données ne résident que dans cette instance particulière. Les autres objets de la même classe ont leurs propres copies distinctes.
Cela devient particulièrement important lors du stockage de données complexes comme des tables. Considérez un système d'inventaire où chaque personnage transporte différents objets :
local Inventory = {}
Inventory.__index = Inventory
function Inventory:new()
local instance = {}
setmetatable(instance, self)
instance.items = {} -- Chaque instance reçoit sa propre table vide
return instance
end
function Inventory:addItem(item)
table.insert(self.items, item)
endLa ligne clé est instance.items = {}. En créant une nouvelle table vide à l'intérieur du constructeur, chaque objet d'inventaire reçoit sa propre liste distincte. Si vous définissiez plutôt items dans la table de classe elle-même, toutes les instances partageraient accidentellement la même table — ajouter une épée à un personnage la donnerait à tout le monde !
local bag1 = Inventory:new()
local bag2 = Inventory:new()
bag1:addItem("Sword")
bag2:addItem("Potion")
print(#bag1.items) -- Sortie : 1
print(#bag2.items) -- Sortie : 1Chaque inventaire conserve sa propre collection. Ce modèle s'applique dès qu'une instance doit suivre des données qui évoluent indépendamment — des listes, des compteurs ou tout état mutable unique à cet objet.
Défi
FacileConstruisons un système de ShoppingCart où chaque panier maintient sa propre liste de produits séparée. Cela démontrera comment les variables d'instance gardent les données isolées entre les objets — ajouter des articles à un panier n'affectera pas l'autre !
Vous organiserez votre code sur deux fichiers :
ShoppingCart.lua: Définissez votre classeShoppingCartoù chaque instance possède sa propre tableproducts. Incluez :- Un constructeur
:new()qui initialise une liste de produits vide pour chaque panier - Une méthode
:addProduct(productName)qui ajoute un produit à la liste de ce panier - Une méthode
:listProducts()qui affiche chaque produit sur une ligne séparée
- Un constructeur
main.lua: Chargez votre module ShoppingCart et créez deux paniers distincts. Ajoutez différents produits à chaque panier pour prouver qu'ils maintiennent des inventaires indépendants.
Vous recevrez quatre entrées :
- Premier produit à ajouter au panier A
- Deuxième produit à ajouter au panier A
- Premier produit à ajouter au panier B
- Deuxième produit à ajouter au panier B
Dans votre fichier principal :
- Créez deux paniers d'achat :
cartAetcartB - Ajoutez les deux premiers produits à
cartA - Ajoutez les deux derniers produits à
cartB - Affichez
Cart A:puis listez les produits du panier A - Affichez
Cart B:puis listez les produits du panier B
Par exemple, si les entrées sont Apple, Bread, Milk, et Eggs, la sortie devrait être :
Cart A:
Apple
Bread
Cart B:
Milk
EggsRappel : la clé est d'initialiser products comme une nouvelle table vide à l'intérieur du constructeur. Cela garantit que chaque instance de panier reçoit sa propre liste séparée plutôt que de partager une seule table entre tous les paniers.
Aide-mémoire
Les variables d'instance sont des champs qui appartiennent exclusivement à un seul objet. Lorsque vous assignez une valeur à self.something à l'intérieur d'une méthode ou d'un constructeur, cette donnée ne vit que dans cette instance particulière.
Pour créer des variables d'instance, initialisez-les à l'intérieur du constructeur en utilisant une nouvelle table pour chaque instance :
local Inventory = {}
Inventory.__index = Inventory
function Inventory:new()
local instance = {}
setmetatable(instance, self)
instance.items = {} -- Chaque instance reçoit sa propre table vide
return instance
end
function Inventory:addItem(item)
table.insert(self.items, item)
endLa clé est instance.items = {} — la création d'une nouvelle table vide à l'intérieur du constructeur garantit que chaque objet reçoit ses propres données distinctes. Si vous définissiez items dans la table de classe elle-même, toutes les instances partageraient la même table.
local bag1 = Inventory:new()
local bag2 = Inventory:new()
bag1:addItem("Sword")
bag2:addItem("Potion")
print(#bag1.items) -- Résultat : 1
print(#bag2.items) -- Résultat : 1Chaque instance maintient sa propre collection de manière indépendante. Ce modèle s'applique à tout état mutable propre à un objet — listes, compteurs ou autres données qui changent par instance.
Essayez vous-même
-- Charger le module ShoppingCart
local ShoppingCart = require('ShoppingCart')
-- Lire les entrées
local product1 = io.read()
local product2 = io.read()
local product3 = io.read()
local product4 = io.read()
-- TODO : Créer deux paniers d'achat : cartA et cartB
-- TODO : Ajouter product1 et product2 à cartA
-- TODO : Ajouter product3 et product4 à cartB
-- TODO : Afficher "Cart A:" puis lister les produits de cartA
-- TODO : Afficher "Cart B:" puis lister les produits de cartB
Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.
Toutes les leçons de Object Oriented Programming
1Le concept de « self »
Tables avec fonctions« self » expliciteLa syntaxe avec deux-pointsPoint vs deux-pointsRécapitulatif - Point mobile4Projet : Banque numérique
Configuration du projetMéthode de dépôt7Polymorphisme et Redéfinition
Redéfinition de méthodesAppeler des méthodes parentesDuck TypingInterface communeVérification du typeRécapitulatif - Rôles des employés10Projet : Gestionnaire de formes
Configuration du projetClasse Rectangle2Modèle de prototype de classe
Le concept de prototypeLiaison avec __indexLe constructeur :new()Initialisation des attributsInstances indépendantesRécapitulatif - Usine de voitures5Surcharge d'opérateurs en POO
Additionner des objetsSoustraire des objetsConcaténer des objetsComparer des objets (<, >)Récapitulatif - Calculs de portefeuille8Encapsulation
Conventions de nommageClosures pour la confidentialitéAccès via les ClosuresTables en lecture seuleLogique de validationRécapitulatif - Coffre-fort sécurisé11Patrons de conception (Lite)
Fonctions FactoryTable SingletonPatron IteratorObserver (Écouteur)Récapitulatif - Logger Factory3État et comportement des objets
Variables d'instanceMéthodes GetterMéthodes SetterPropriétés calculéesFormatage de chaînesVérifications d'égalitéRécapitulatif - Note de l'étudiant6Bases de l'héritage
Mise en place de l'héritageHériter des méthodesÉtendre le constructeurAjouter des méthodes enfantsPartagé vs UniqueRécapitulatif - Hiérarchie des formes