I. Définition▲
Globalement une classe est un schéma détaillant la constitution et le fonctionnement d'un objet. Une classe définit les méthodes et les propriétés d'un objet. Lorsque 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.
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.
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.
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.
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.
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.
// 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.
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 :
Édition > 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'autres 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 chemins de classe qui seront utilisés pour ce projet 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, utiliser 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.
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 :
class
Paquet.
SousPaquet1.
SousPaquet2.
ClasseTest
Voyons maintenant la création d'occurrences d'une classe contenue dans un paquet :
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 :
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 :
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 ait 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 :
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 :
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 seule fois en utilisant la méthode GET / SET, voici comment créer la classe Banque :
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 :
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 :
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éthodes 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 permettent ses changements :
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é :
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 à 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 composent. 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 :
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 contrôler la valeur privée
}
public
function
getVarStatique
(
):
Number
{
return
varStatique;
// Methode pour contrôler 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 :
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 une 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 :
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 :
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 :
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 :
https://stephaneey.developpez.com/tutoriel/flashmx2004/composant/#L2
X. Remerciements▲
Je remercie tout particulièrement Alexandra de comprendre mon travail et de 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é sur cette page, tout particulièrement freegreg, BrYs, Nono40, Mathieu…