I. Définition

Globalement une classe est un schéma détaillant la constitution et le fonctionnement d'un objet. Une classe définie les méthodes et les propriétés d'un objet. Lorsque que vous utilisez un objet, vous utilisez en réalité une instance de celui-ci qui possède toutes les propriétés et méthodes définies dans la classe. Je vous renvoie à la définition d'objet et de classe de hdd34.

Pour créer une occurrence (ou instance) d'une classe, on invoque la méthode constructeur de celle-ci.

 
Sélectionnez
var monTableau:Array = new Array();

Le membre de droite exécute la méthode constructeur.

Il n'est pas possible de recourir directement à la classe Array sans créer une occurrence de la classe afin de pouvoir utiliser ses propriétés et ses méthodes.

Il existe certaines classes de haut niveau qui n'ont pas besoin de créer d'occurrence. On peut par exemple utiliser Math, Mouse et Key sans utiliser la méthode constructeur.

II. Création d'une Classe

II-A. Création d'une Classe Cube.as

Une classe est toujours définie en externe dans un fichier nommé [Nomclass].as et il ne peut y avoir qu'une classe par fichier. En général, on fait commencer les noms de classe par une majuscule. Une classe peut être créée à partir de l'éditeur d'ActionScript de Flash ou bien avec un simple bloc note. Le fichier contient la classe, ses méthodes et ses propriétés.

 
Sélectionnez
class Cube {

}

Voici le début d'une classe valide contenue dans un fichier Cube.as.

Il reste encore à définir les propriétés et les méthodes adéquates.

 
Sélectionnez
class Cube {
    var longueur:Number = 3;
    var largeur:Number = 7;
    var hauteur:Number = 2;
    
    function Volume():Number {
        return longueur*hauteur*largeur;
    }
}

Il y a donc trois propriétés dans l'exemple et une méthode Volume() qui sont donc tous membres de Cube.

Afin de pouvoir exploiter au mieux la classe, nous allons créer la méthode constructeur et modifier les paramètres afin de les personnaliser.

 
Sélectionnez
class Cube {
    var longueur:Number;
    var largeur:Number;
    var hauteur:Number;
    
    function Cube(longueurTemp:Number, hauteurTemp:Number, largeurTemp:Number) {
        longueur = longueurTemp;
        largeur = largeurTemp;
        hauteur = hauteurTemp;
    }
    
    function Volume():Number {
        return longueur*hauteur*largeur;
    }
}

Il suffit maintenant d'enregistrer cette classe dans Cube.as placé dans le même dossier que l'application et de tester s'il est possible d'utiliser cette nouvelle classe.

II-B. Utiliser votre Classe Cube.as

Sur une image du scénario de l'application, ouvrir le panneau action.

 
Sélectionnez
var monCube:Cube = new Cube(3,2,7);
var monVolume:Number = monCube.Volume();

Par défaut, les propriétés et les méthodes disponibles dans une occurrence d'une classe sont fixées par son fichier de classe. On ne peut donc pas définir la propriété Color de notre monCube puisqu'elle n'est pas définie dans sa classe.

 
Sélectionnez
// obtenir les propriétés
monCube.longueur; //vaut 3
monCube.Volume(); //renvoie 42

// définir les propriétés
monCube.longueur = 6;

Par contre il est impossible de définir la couleur du Cube.

 
Sélectionnez
monCube.color = "red";

III. Le chemin de classe

Pour faire appel à une classe dans flash, l'application doit savoir où trouver les fichiers .as lors de la compilation. Afin d'inclure la classe dans le swf, flash recherche dans le chemin de classe.

Il existe un chemin global où l'on peut stocker des classes, par défaut il correspond au dossier qui stocke les classes de base comme Array.as, Date.as ou bien Color.as.

Ce répertoire se trouve sous Windows XP sur :
Program Files\Macromédia\Flash MX 2004\fr\First Run\Classes

Attention, toutes les classes contenues dans ce dossier et dans les sous-dossiers affectent tous les .FLA créés sur le poste, c'est-à-dire que si vous stockez vos classes ici, tous vos projets accéderont à ces classes. Attention aussi à ne pas faire n'importe quoi avec les classes existantes.

Il existe un chemin lié au projet, c'est-à-dire qu'il ne touche que le projet concerné et non tous les projets de votre ordinateur. Il correspond en fait à la racine de votre projet flash.

Il est possible aussi de modifier ou de créer d'autres chemins globaux afin de ne pas stocker toutes vos classes dans le dossier global des classes de flash. Pour cela il suffit d'ouvrir flash et de procéder comme suit :
Edition > Préférences > ActionScript > Paramètres d'Actionscript 2.0
puis en cliquant sur le + il est possible d'ajouter des chemins de classe qui seront utilisés pour chacun de vos projets.

Il est possible aussi de modifier ou de créer d'autre chemins liés afin de ne pas stocker toutes vos classes dans le dossier racine de votre projet. Pour cela il suffit d'ouvrir un projet et de procéder comme suit :
Fichier > Paramètres de publication > Flash > Paramètres d'actionscript 2.0
puis en cliquant sur le + il est possible d'ajouter des chemin de classe qui seront utilisés pour ce projets uniquement.

À la différence des chemins globaux, il est maintenant possible de définir l'endroit du scénario où la classe va être chargée, vous remarquerez que l'option : Exporter l'image pour les classes n'est plus grisée et qu'il est possible de spécifier un numéro. Ce numéro correspond au numéro de l'image qui charge les classes, utilisez une autre image que l'image 1 permet de faire un préchargement des classes.

IV. Paquet et importation de classes

Pour s'y retrouver entre toutes les classes, il peut être pratique de les ranger dans des dossiers et des sous-dossiers. En ActionScript, un sous-dossier dans un chemin de classe est appelé un paquet et peut contenir d'autres classes ainsi que des sous-paquets.

L'utilisation de paquet influe sur le code de création des classes car quelques modifications s'imposent.

 
Sélectionnez
class PaquetTest.ClasseTest {
    function ClassTest() {
        // Constructeur
    }
}

Vous avez pu remarquer le léger changement avec l'ajout du paquet avant le nom de la classe.

Dans le cas de sous-paquet la syntaxe est la suivante :

 
Sélectionnez
class Paquet.SousPaquet1.SousPaquet2.ClasseTest

Voyons maintenant la création d'occurrence d'une classe contenue dans un paquet :

 
Sélectionnez
var monOccurence:PaquetTest.ClasseTest = new PaquetTest.ClasseTest();

Pour éviter d'avoir des lignes de commande trop longues, il est possible d'importer la classe au début du code afin de n'utiliser que son nom par la suite :

 
Sélectionnez
import PaquetTest.ClasseTest; var monOccurence:ClasseTest = new ClasseTest();

il est aussi possible d'importer toutes les classes d'un paquet sans les spécifier une par une :

 
Sélectionnez
import PaquetTest.*

Attention, le fait d'importer la totalité des classes d'un paquet n'inclut pas les sous-paquets.

Attention, un import sur l'image 1 ne permet pas d'utiliser la formule abrégée sur les autres images. On doit donc importer les classes sur chaque image qui utilise les abréviations.

V. GET et SET

Avant de voir comment utiliser la méthode Get et Set, voyons plutôt pourquoi je vais vous parler de cela car il est vrai que tout marche bien sans.

Imaginons que l'on ai une classe Banque qui dispose de propriété comme les bénéfices. Voici comment vous auriez rentré la valeur de la propriété benefice sans la méthode GET/SET :

 
Sélectionnez
var maBanque:Banque = new Banque();
maBanque.benefice = 600000000;

Maintenant, je vous demande de faire la même chose pour 150 banques, c'est long mais faisable sans problème. Mais comme je n'ai pas réfléchi avant de vous le demander, j'ai oublié de vous dire qu'il fallait enlever 5% à tous les bénéfices des 150 banques. Avec cette méthode, vous devez modifier les 150 lignes de codes par :

 
Sélectionnez
var maBanque:Banque = new Banque();
maBanque.benefice = 600000000 - (600000000*(5/100));

Pour ne plus avoir ce problème, il est possible d'effectuer la modification une seul fois en utilisant la méthode GET / SET, voici comment créer la classe Banque :

 
Sélectionnez
class Banque {
    var benefice:Number;
    
    function Banque() {
        // fonction constructeur
    }
    
    function setBenefice(num:Number) {
        benefice = num - (num*(5/100));
    }
    
    function getBenefice():Number {
        return benefice;
    }
}

Grâce à cette nouvelle classe, les 150 lignes ne sont plus à modifier, de plus on est plus obligé de se soucier du calcul qui est fait à l'intérieur de la fonction. Voici comment utiliser ces nouvelles méthodes :

 
Sélectionnez
maBanque.setBenefice(600000000);
maBanque.getBenefice(); // renvoi 570000000

Maintenant que vous avez compris comment fonctionne GET / SET et ce qu'ils permettent de faire, voyons comment les optimiser au mieux.

Observez la classe suivante :

 
Sélectionnez
class Banque {
    var banqueBenefice:Number;
    
    function Banque() {
        // fonction constructeur
    }
    
    function set benefice(num:Number) {
        banqueBenefice = num - (num*(5/100));
    }
    
    function get benefice():Number {
        return banqueBenefice;
    }
}

La grande différence est que l'on a modifié nos propres méthode setBenefice et getBenefice par les méthodes implicites de flash get et set. C'est-à-dire que l'on utilise maintenant les fonctions de flash ce qui nous permet une plus grande liberté d'utilisation, voici ce que permet ses changements :

 
Sélectionnez
maBanque.benefice = 600000000;
trace(maBanque.benefice); // renvoi 570000000

Il est important de voir que nous avons changé la variable benefice en banqueBenefice afin d'éviter une erreur car rappelez vous de mon premier exemple des 150 banques, j'avais utilisé :

 
Sélectionnez
maBanque.benefice = 600000000

En comparant avec la syntaxe que je viens de vous montrer, vous remarquerez qu'il n'y a pas de différence alors comment voulez vous que flash face la différence entre le fait de définir la propriété benefice ou l'appel de la méthode set benefice ? Le changement de la variable Benefice en banqueBenefice permet d'éviter cette erreur.

Important, si vous ne vous sentez pas à l'aise avec l'utilisation du GET/SET implicite, il est tout a fait possible d'utiliser vos propres méthodes GET/SET comme dans mon deuxième exemple, le seul avantage de la méthode implicite est le gain de temps lors de la saisie.

VI. Définition des membres Privés, Publics, Statiques

Les membres d'une classe sont les fonctions, les constantes et les variables qui la compose. Par défaut, chaque membre est public, c'est-à-dire que l'on peut y accéder depuis les occurrences créées à partir de la classe.

Voici un exemple de classe utilisant les membres privés, statique et public :

 
Sélectionnez
class ClassTest {
    private var varPrive:Number; //variable utilisée pour le calcul
    static var varStatique:Number = 10; //variable idem pour toutes les occurrences
    public var varPublique:String; //valeur accessible par l'occurrence
    
    function ClassTest {
        // constructeur
    }
    
    public function setTest(num:Number) {
        varPrive = num * varStatique;
        varPublique = "numéro " + varPrive;
    }
    
    public function getTest():String {
        return varPrive; // Methode pour controler la valeur privée
    }
    
    public function getVarStatique():Number {
        return varStatique; // Methode pour controler la valeur statique
    }
}

Prenons le temps de bien voir la différence entre chaque définition de membre.

La définition PRIVATE permet d'utiliser le membre uniquement dans la classe, ainsi une occurrence de cette classe ne peut pas y accéder.

La définition PUBLIC permet d'utiliser le membre en interne et en externe, ainsi une occurrence de cette classe peut y accéder.

La définition STATIC permet de définir une propriété fixe pour toutes les occurrences issues de cette classe, par exemple une Taxe s'appliquant à la classe Produits.

Voici les utilisations possibles ou non :

 
Sélectionnez
var occurenceTest:ClassTest = new ClassTest();
var occurenceTest2:ClassTest = new ClassTest();
var occurenceTest3:ClassTest = new ClassTest();
trace(occurenceTest.varPrivee); // Erreur car non accessible
occurenceTest.varPrivee = 4; // Erreur car non accessible
occurenceTest.varPublique = "numéro 3" // définit la propriété
trace(occurenceTest.varPublique); // renvoie "numéro 3"
occurenceTest.setTest(8);
trace(occurenceTest.varPrivee); // Erreur car non accessible
trace(occurenceTest.varPublique);  //renvoie "numéro 80"
trace(occurenceTest.getTest());  //renvoie 80  (8 * 10)
trace(ClassTest.varStatique); //renvoie 10 valeur par défaut
trace(occurenceTest.getVarStatique());// renvoie "10"
ClassTest.varStatique = 15; // définit la propriété
trace(ClassTest.varStatique); // renvoie "15"
trace(occurenceTest.varStatique); // Erreur je crois à vérifier ;)
trace(occurenceTest.getVarStatique());// renvoie "15"
trace(occurenceTest2.getVarStatique());// renvoie "15"
trace(occurenceTest3.getVarStatique());// renvoie "15"
occurenceTest.setTest(8);
trace(occurenceTest.getTest());  //renvoie 120 (8 * 15)

VII. L'héritage des classes

Une des notions importantes dans la création d'une classe est l'héritage de classe. Une classe peut hériter des propriétés et des méthodes d'une autre classe. La classe qui hérite est une sous-classe, la classe qui offre ses membres est un super-classe.

Le grand avantage est de pouvoir réutiliser des classes personnelles sans avoir à ressaisir le code, mais aussi d'utiliser les membres d'une classe de flash.

Afin de mieux comprendre, voici un exemple concret. Imaginez que vous êtes en train de créer un jeu de rôle. Vous pouvez écrire une classe Personnage qui aura comme méthode Marcher(), vous pouvez ensuite créer deux sous-classes Gentil et Mechant avec comme méthodes respectives jouer() et piller(). Une instance de Mechant pourra donc marcher et piller alors qu'une instance de Gentil pourra marcher et jouer.

Pour se faire, on utilise le mot extends :

 
Sélectionnez
class Gentil extends Personnage {
    function Gentil() {
        // Constructeur
    }
}

À noter que l'héritage se fait lors de la compilation de flash. Les classes ne sont donc pas à placer avec vos fichiers swf.

Attention, une classe ne peut hériter que d'une seule autre classe, autrement dit, il ne peut exister qu'une seule super-classe par classe.
Il est donc nécessaire d'utiliser les classes en cascade car une sous-classe peut, par contre, devenir la super-classe d'une autre classe.

Nous voulons maintenant qu'une instance d'une nouvelle classe Commercant puisse hériter des membres de la classe Personnage ainsi que de la classe Gentil. L'exemple suivant vous montre comment imbriquer plusieurs classes ensemble :

 
Sélectionnez
class Commercant extends Gentil {
    function Commercant() {
        // Constructeur
    }
}
// la classe Gentil héritant de la classe Personnage.

L'héritage de classe permet de transmettre tous les membres d'une classe à une autre. Il peut donc arriver que des propriétés ou des méthodes soient définies dans la super-classe ainsi que dans la sous-classe. Dans ce cas, les méthodes et propriétés de la sous-classe sont prioritaires.

La dernière chose qui semble importante à voir c'est que l'on puisse faire un héritage d'une classe flash vers une classe personnelle. Ceci revient à étendre les possibilités des classes présentes dans flash. Imaginez qu'une classe Array ne vous apporte pas entière satisfaction. Vous pouvez créer une nouvelle classe MaArray qui hérite de Array et qui dispose de nouvelles méthodes.

Prenons l'exemple d'une classe Window, permettant de créer des fenêtres d'applications. Si vous souhaitez que vos instances de classe puissent bénéficier de la propriété _visible :

 
Sélectionnez
class Windows extends MovieClip {
    function Windows() {
        // Constructeur
    }
}
// la classe MovieClip possède une propriété _visible.

VIII. Conclusion

Pour conclure, je dirais que pour maîtriser les classes, il faut tout d'abord se rendre compte de leur importance. Ensuite, il suffit de s'exercer pour mieux comprendre les possibilités et leurs fonctionnements. Ce cours vous donne les points principaux pour commencer, même si tout n'est pas clair pour vous à la première lecture, n'hésitez pas à revenir ici après avoir essayé par vous-même.

IX. Liens

Je vous propose l'article de Stéphaneey en complément d'information :
http://stephaneey.developpez.com/tutoriel/flashmx2004/composant/#L2

X. Remerciements

Je remercie tout particulièrement Alexandra, pour comprendre mon travail et pour me soutenir dans tout ce que je fais. Je t'aime.

Je remercie developpez.com pour donner aux développeurs, la chance de s'exprimer, de s'entraider, et de s'épanouir.

Je remercie les relecteurs qui ont travaillés sur cette page, tout particulièrement freegreg, BrYs, Nono40, Mathieu ...