Propriétés calculées
Fait partie de la section Programmation orientée objet 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 !
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 Programmation orientée objet
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 RectangleClasse CercleMéthode PérimètreCollection de formesAire totaleFiltrer les formes2Modè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