Propriétés calculées
Fait partie de la section Object Oriented Programming du Journey Lua de Coddy — leçon 15 sur 70.
Les getters et les setters permettent d'accéder aux valeurs stockées, mais vous avez parfois besoin de données qui n'existent pas en tant que champ stocké — elles doivent être calculées à partir d'autres attributs. C'est ce qu'on appelle des propriétés calculées.
Considérez un rectangle. Vous stockez sa largeur et sa hauteur, mais l'aire n'est stockée nulle part — elle est calculée en multipliant ces deux valeurs ensemble. Au lieu de stocker des données redondantes, vous créez une méthode qui calcule et renvoie le résultat :
local Rectangle = {}
Rectangle.__index = Rectangle
function Rectangle:new(width, height)
local instance = {}
setmetatable(instance, self)
instance.width = width
instance.height = height
return instance
end
function Rectangle:getArea()
return self.width * self.height
endLa méthode :getArea() ne retourne pas une valeur stockée — elle calcule la surface à nouveau à chaque fois que vous l'appelez. Cette approche présente un avantage clé : si la largeur ou la hauteur change, la surface reflète automatiquement les nouvelles dimensions sans que vous ayez besoin de mettre quoi que ce soit à jour.
local box = Rectangle:new(5, 3)
print(box:getArea()) -- Sortie : 15
box.width = 10
print(box:getArea()) -- Sortie : 30Les propriétés calculées maintiennent la cohérence de vos objets. Plutôt que de stocker des valeurs qui dépendent d'autres champs (et de risquer qu'elles deviennent obsolètes), vous les calculez à la demande. Ce modèle s'applique à toutes les données dérivées : périmètres, moyennes, chaînes formatées ou toute valeur pouvant être déterminée à partir d'attributs existants.
Défi
FacileConstruisons une classe Box qui calcule son volume à la demande ! Au lieu de stocker le volume en tant que champ, vous allez créer une propriété calculée qui le calcule à partir des dimensions de la boîte chaque fois que cela est nécessaire.
Vous organiserez votre code sur deux fichiers :
Box.lua: Définissez votre classeBoxavec le modèle de prototype standard. Chaque boîte stocke trois dimensions :width,height, etdepth. Incluez :- Un constructeur
:new(width, height, depth)qui stocke les trois dimensions - Une méthode
:getVolume()qui calcule et retourne le volume (width × height × depth) - Une méthode
:getSurfaceArea()qui calcule et retourne la surface totale
- Un constructeur
main.lua: Importez votre module Box, créez une instance de boîte et démontrez comment les propriétés calculées reflètent automatiquement les dimensions actuelles.
La surface d'une boîte est calculée comme suit : 2 × (width×height + height×depth + width×depth)
Vous recevrez trois entrées représentant les dimensions de la boîte :
- Largeur (Width)
- Hauteur (Height)
- Profondeur (Depth)
Dans votre fichier principal, créez une boîte avec les dimensions données, puis affichez deux lignes :
- Le volume en utilisant
:getVolume() - La surface en utilisant
:getSurfaceArea()
Par exemple, si les entrées sont 3, 4, et 5, la sortie devrait être :
60
94La beauté des propriétés calculées est qu'elles restent toujours exactes. Si vous modifiez ultérieurement l'une des dimensions de la boîte, appeler à nouveau :getVolume() retournera automatiquement la nouvelle valeur correcte — aucune mise à jour manuelle n'est nécessaire !
Aide-mémoire
Les propriétés calculées sont des méthodes qui calculent et renvoient des valeurs basées sur d'autres attributs plutôt que de les stocker directement. Cela garantit la cohérence des données et élimine la redondance.
Exemple d'une propriété calculée pour l'aire :
local Rectangle = {}
Rectangle.__index = Rectangle
function Rectangle:new(width, height)
local instance = {}
setmetatable(instance, self)
instance.width = width
instance.height = height
return instance
end
function Rectangle:getArea()
return self.width * self.height
endLa méthode :getArea() calcule l'aire à chaque fois qu'elle est appelée, reflétant automatiquement tout changement de largeur ou de hauteur :
local box = Rectangle:new(5, 3)
print(box:getArea()) -- Résultat : 15
box.width = 10
print(box:getArea()) -- Résultat : 30Les propriétés calculées sont utiles pour toutes les données dérivées telles que les périmètres, les volumes, les moyennes ou les chaînes formatées qui peuvent être déterminées à partir d'attributs existants.
Essayez vous-même
-- Charger le module Box
local Box = require('Box')
-- Lire les dimensions d'entrée
local width = tonumber(io.read())
local height = tonumber(io.read())
local depth = tonumber(io.read())
-- TODO : Créer une instance de boîte avec les dimensions données
-- TODO : Afficher le volume en utilisant :getVolume()
-- TODO : Afficher l'aire de surface en utilisant :getSurfaceArea()
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