Forums Développement Multimédia

Les formations Mediabox
Les formations Mediabox

L'encapsulation des variables

Compatible ActionScript 2. Cliquer pour en savoir plus sur les compatibilités.Par thecaptain

Article issu du forum, écrit par thecaptain le 19 juin 2004

Connaissances requises

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 ;-)