L'encapsulation des variables
Article issu du forum, écrit par thecaptain le 19 juin 2004
Connaissances requises
- syntaxe Actionscript 2
Niveau
débutant/intermédiaire
But
Maitriser les getter setter et comprendre leur utilisation
Introduction
Lorsque l'on parle de classes en AS2, on arrive tôt ou tard sur le concept d'encapsulation des variables. Cela consiste à 'protéger' l'accès des variables d'instance en obligeant l'utilisateur à passer par des getters/setters. Prenons un exemple simple :
//== Voiture.as == class Voiture { //VARIABLE public var _prix:Number; //CONSTRUCTEUR public function Voiture(prix:Number) { //initialisation this._prix = 0; if (prix != undefined) { this._prix = prix; } } }
//== testVoiture1.fla == import Voiture; var test:Voiture = new Voiture(10000); trace(test._prix); //10000
Dans ce code, le concept d'encapsulation des variables est faible, même inexistante. En effet, vous pouvez accéder à la variable d'instance _prix directement et la modifier comme vous voulez ! :?
Les getters/setters
les getters/setters vont servir à faire des vérifications dans le but que l'utilisateur ne puisse pas entrer n'importe quoi comme valeur. Exemple :
//== Voiture.as == class Voiture { //VARIABLE private var _prix:Number; //GETTER public function getPrix(Void):Number { return this._prix; } public function getPrixNet(Void):Number { return this._prix*100/107.6; //c'est un exemple de calcul pour la tva (suisse :D) } //SETTER public function setPrix(newPrix:Number):Void { if (newPrix > 0) { this._prix = newPrix; } } //CONSTRUCTEUR public function Voiture(prix:Number) { //initialisation this._prix = 0; //on met le nouveau prix setPrix(prix); } }
//== testVoiture2.fla == import Voiture; var test:Voiture = new Voiture(10000); //trace(test._prix); //Erreur lors de la compilation --> membre is private and cannot be accessed test.setPrix(-123); trace(test.getPrix()); //10000 --> rien n'a changé car le nouveau prix est invalide
Ici, il y a une bonne encapsulation des variables : l'utilisateur ne peux pas entrer de prix négatif, ce qui constitue déjà un gros avantage par rapport à l'autre . Bien entendu vous pouvez multiplier ces vérifications dans le but de délimiter précisément la tranche de prix que vous voulez permettre.
Le but est que les seules méthodes modifiant et lisant réellement vos variables d'instance soient justement les getters/setters et que toutes les autres méthodes de votre classes ayant recours aux variables les utilisent. Cela évite bien évidemment des vérifications ultérieures à l'intérieur de vos fonction et de plus, en cas de problème de modification, vous savez exactement quelle méthode modifie quelle variable.
Les getters/setters avancés
Nous avons vu maintenant le principe d'utilisation. Maintenant penchons nous sur l'instruction suivante :
monMovieClip._alpha = 185; trace(monMovieClip._alpha); //100
Comment la vérification est-elle faite ici pour que la propriété _alpha du clip soit à 100 au maximum ??? Une des possibilités est justement d'utiliser les getters/setters avancés. Voyez plutot :
//== Voiture.as == class Voiture { //VARIABLE private var _prix:Number; //GETTER public function get prix():Number { return this._prix; } public function get prixNet():Number { return this._prix*100/107.6; //c'est un exemple de calcul pour la tva (suisse :D) } //SETTER public function set prix(newPrix:Number) { if (newPrix > 0) { this._prix = newPrix; } } //CONSTRUCTEUR public function Voiture(lePrix:Number) { //initialisation this._prix = 0; //on met le nouveau prix this.prix = lePrix } }
//== testVoiture3.fla import Voiture; var test:Voiture = new Voiture(10000); trace(test.prix); //10000 test.prix = -5; trace(test.prix); //10000 test.prix = 150; trace(test.prix); //150
Il y a plusieurs choses à noter dans cet exemple. Tout d'abord côté synthaxe AS2, pour les setters, on n'indique pas de retour (ce qui est logique) et pas de paramètre pour les getters (ce qui est logique aussi . Notez aussi qu'un setter ne peut prendre qu'un et un seul paramètre (s'il y en a pas c'est un getter)
. Ensuite remarquez ceci dans le constructeur :
this.prix = lePrix
On appelle le setter prix qui va recevoir la variable lePrix en paramètre et effectuer les vérifications implémentées dans le setter. Vous l'aurez compris, les getters fonctionnent de la même façon. Le choix que vous faites pour l'encapsulation de vos variables dépend de votre préférence. Cette méthode et la précédente sont absolument équivalentes
Sur ce, bonne étude
