Une classe est une représentation abstraite d’un objet. Une classe conserve des informations sur les types de données contenues par un objet et sur les comportements possibles de cet objet. L’utilité de ce niveau d’abstraction peut ne pas être évidente dans le cas de petits scripts ne contenant que quelques objets destinés à interagir les uns avec les autres. Cependant, au fur et à mesure qu’un programme croît en ampleur, le nombre d’objets à gérer augmente. Les classes autorisent alors un meilleur contrôle sur la création des objets et sur leurs interactions.
Dès la première version d’ActionScript, les programmeurs en ActionScript pouvaient utiliser des objets Function pour créer des éléments ressemblant à des classes. ActionScript 2.0 a ensuite ajouté une prise en charge formelle des classes, avec des mots-clés tels que
class
et
extends
. De son côté, ActionScript 3.0 préserve la prise en charge des mots-clés introduits avec ActionScript 2.0, tout en ajoutant de nouvelles possibilités : par exemple un meilleur contrôle d’accès avec les attribut
protected
et
internal
, ainsi qu’un meilleur contrôle de l’héritage avec les mots-clés
final
et
override
.
Si vous avez déjà créé des classes dans des langages de programmation tels que Java, C++ ou C#, vous ne serez pas dépaysé par ActionScript. ActionScript partage avec ces langages de nombreux mots-clés et noms d’attributs, comme
classe
,
extends
et
public
.
Remarque :
dans la documentation Adobe ActionScript, le terme propriété désigne tout membre d’un objet ou d’une classe (variables, constantes et méthodes). En outre, bien que les termes classe et statique soient fréquemment utilisés indifféremment, nous ferons une distinction entre ces termes. Par exemple, l’expression « propriétés de classe » désigne tous les membres d’une classe plutôt que ses membres statiques exclusivement.
Définitions de classe
En ActionScript 3.0, les définitions de classe utilisent la même syntaxe qu’en ActionScript 2.0. La syntaxe correcte d’une définition de classe utilise le mot-clé
class
suivi du nom de la classe. Le corps de la définition de classe est inséré entre des accolades (
{}
) après le nom de la classe. Par exemple, le code suivant crée une classe appelée Shape qui contient une variable appelée
visible
:
public class Shape
{
var visible:Boolean = true;
}
Notez que la syntaxe est différente dans le cas des définitions de classe faisant partie d’un package. En ActionScript 2.0, si une classe fait partie d’un package, le nom de ce dernier doit figurer dans la déclaration de classe. Comme l’instruction
package
a été introduite en ActionScript 3.0, le nom du package doit figurer dans la déclaration de package et non pas dans la déclaration de classe. Par exemple, les déclarations de classe suivantes montrent comment la classe BitmapData, qui fait partie du package flash.display, est définie dans ActionScript 2.0 et ActionScript 3.0 :
// ActionScript 2.0
class flash.display.BitmapData {}
// ActionScript 3.0
package flash.display
{
public class BitmapData {}
}
Attributs de classe
ActionScript 3.0 vous permet de modifier des définitions de classe à l’aide de l’un des quatre attributs suivants :
Attribut
|
Définition
|
dynamique
|
Permet d’ajouter des propriétés aux occurrences lors de l’exécution.
|
final
|
Ne doit pas être étendue par une autre classe.
|
interne
(par défaut)
|
Visible pour les références à partir du package actuel.
|
public
|
Visible pour les références à partir de n’importe quel point du code.
|
Pour chacun de ces attributs, à l’exception d’
internal
, vous incluez explicitement l’attribut pour obtenir le comportement qui lui est associé. Par exemple, faute d’inclure l’attribut
dynamic
lors de la définition d’une classe, vous n’êtes pas en mesure d’ajouter des propriétés à une occurrence de classe lors de l’exécution. Pour affecter explicitement un attribut, placez-le au début de la définition de la classe, comme dans le code ci-dessous :
dynamic class Shape {}
Notez que la liste ne contient pas d’attribut appelé
abstract
. En effet, les classes abstraites ne sont pas prises en charge en ActionScript 3.0. Notez également que la liste ne comprend pas non plus les attributs
private
et
protected
. Ces attributs n’ont de signification qu’au sein d’une définition de classe et ne peuvent être appliqués aux classes elles-mêmes. Si vous ne souhaitez pas qu’une classe soit visible hors de son package, placez-la au sein d’un package et affectez la classe de l’attribut
internal
. Autrement, vous pouvez omettre les attributs
internal
et
public
et le compilateur ajoutera automatiquement l’attribut
internal
pour vous. Vous pouvez également définir une classe afin qu’elle soit uniquement visible à l’intérieur du fichier source dans lequel elle est définie. Pour ce faire, placez-la à la fin de ce fichier source, après l’accolade de fin de la définition du package.
Corps de la classe
Le corps de la classe, qui est entouré d’accolades, définit les variables, les constantes et les méthodes de la classe. L’exemple suivant illustre la déclaration de la classe Accessibility dans ActionScript 3.0 :
public final class Accessibility
{
public static function get active():Boolean;
public static function updateProperties():void;
}
Vous pouvez aussi définir un espace de noms au sein d’un corps de classe. L’exemple suivant montre la définition d’un espace de noms dans le corps d’une classe et son utilisation comme attribut d’une méthode de cette classe :
public class SampleClass
{
public namespace sampleNamespace;
sampleNamespace function doSomething():void;
}
ActionScript 3.0 vous permet d’inclure dans un corps de classe non seulement des définitions, mais également des instructions. Les instructions qui figurent dans le corps d’une classe, mais hors d’une définition de méthode, sont exécutées une seule fois, lors de la première apparition de la définition de classe et de la création de l’objet class qui lui est associé. L’exemple suivant comprend un appel vers une fonction externe,
hello()
et une instruction
trace
qui affiche un message de confirmation lorsque la classe est définie.
function hello():String
{
trace("hola");
}
class SampleClass
{
hello();
trace("class created");
}
// output when class is created
hola
class created
En ActionScript 3.0, il est permis de définir une propriété statique et une propriété d’occurrence portant le même nom dans le corps de la même classe. Par exemple, le code suivant déclare une variable statique appelée
message
et une variable d’occurrence du même nom :
class StaticTest
{
static var message:String = "static variable";
var message:String = "instance variable";
}
// In your script
var myST:StaticTest = new StaticTest();
trace(StaticTest.message); // output: static variable
trace(myST.message); // output: instance variable
Attributs de propriété de classe
Dans le cadre du modèle d’objet ActionScript, le terme
propriété
représente tout ce qui peut être membre d’une classe : variables, constantes et méthodes. Ce terme est utilisé de manière plus restrictive dans le manuel Guide de référence du langage et des composants ActionScript 3.0 : il ne désigne alors que les membres d’une classe qui sont des variables ou qui sont définis par une méthode de lecture/définition. En ActionScript 3.0, il existe un jeu d’attributs qui peut être utilisé avec n’importe quelle propriété de classe. Le tableau suivant présente ce jeu d’attributs.
Attribut
|
Définition
|
internal
(par défaut)
|
Visible pour les références au sein d’un même package.
|
private
|
Visible pour les références au sein d’une même classe.
|
protected
|
Visible pour des références au sein d’une même classe et de classes dérivées.
|
public
|
Visible pour des références en tous lieux.
|
static
|
Spécifie qu’une propriété appartient à la classe et non pas aux occurrences de la classe.
|
UserDefinedNamespace
|
Nom d’espace de noms défini par l’utilisateur.
|
Attributs d’espace de noms pour le contrôle d’accès
ActionScript 3.0 comporte quatre attributs spéciaux qui contrôlent l’accès aux propriétés définies au sein d’une classe :
public
,
private
,
protected
et
internal
.
Avec l’attribut
public
, une propriété est visible de n’importe quel point du script. Par exemple, si vous souhaitez qu’une méthode soit disponible pour du code externe au package, vous devez la déclarer avec l’attribut
public
. Ceci est valable pour toute propriété, qu’elle soit déclarée à l’aide des mots-clés
var
,
const
ou
function
.
Avec l’attribut
private
, une propriété n’est visible qu’à partir de la classe où cette propriété est définie. Ce comportement est différent de celui de l’attribut
privé
en ActionScript 2.0, où une sous-classe pouvait accéder à une propriété déclarée private d’une superclasse. L’accès en cours d’exécution constitue aussi un changement radical de comportement. En ActionScript 2.0, la restriction d’accès introduite par le mot-clé
private
ne portait que sur la compilation et il était facile de la contourner lors de l’exécution. Cette situation n’existe plus en ActionScript 3.0. Les propriétés désignées comme
private
sont indisponibles, aussi bien au cours de la compilation que de l’exécution.
Par exemple, le code ci-dessous crée une classe simple appelée PrivateExample pourvue d’une variable privée. Elle tente ensuite d’accéder à cette variable depuis un emplacement hors de la classe.
class PrivateExample
{
private var privVar:String = "private variable";
}
var myExample:PrivateExample = new PrivateExample();
trace(myExample.privVar);// compile-time error in strict mode
trace(myExample["privVar"]); // ActionScript 2.0 allows access, but in ActionScript 3.0, this is a run-time error.
En ActionScript 3.0, toute tentative d’accéder à une propriété private à l’aide de l’opérateur point (
myExample.privVar
) déclenche une erreur de compilation en mode strict. Autrement, l’erreur est signalée à l’exécution, tout comme lors de l’utilisation de l’opérateur d’accès à la propriété (
myExample["privVar"]
).
Le tableau suivant présente les divers résultats d’une tentative d’accès à une propriété déclarée comme privée qui appartient à une classe scellée (non dynamique) :
|
Mode strict
|
Mode standard
|
opérateur point (
.
)
|
erreur à la compilation
|
erreur à l’exécution
|
opérateur crochet (
[]
)
|
erreur à l’exécution
|
erreur à l’exécution
|
Dans les classes déclarées avec un attribut
dynamic
, les tentatives d’accès à une variable privée ne provoquent pas d’erreur d’exécution. La variable n’est simplement pas visible, de sorte que la valeur
undefined
est renvoyée. Une erreur à la compilation survient néanmoins si vous utilisez l’opérateur point en mode strict. L’exemple suivant est identique au précédent si ce n’est que la classe PrivateExample est déclarée en tant que classe dynamique :
dynamic class PrivateExample
{
private var privVar:String = "private variable";
}
var myExample:PrivateExample = new PrivateExample();
trace(myExample.privVar);// compile-time error in strict mode
trace(myExample["privVar"]); // output: undefined
Les classes dynamiques renvoient le plus souvent la valeur
undefined
plutôt que de générer une erreur lorsque du code, extérieur à une classe, tente d’accéder à une classe déclarée comme propriété privée. Le tableau suivant montre qu’une erreur est générée uniquement lorsque l’opérateur point est utilisé pour accéder à une propriété privée en mode strict :
|
Mode strict
|
Mode standard
|
opérateur point (
.
)
|
erreur à la compilation
|
undefined
|
opérateur crochet (
[]
)
|
undefined
|
undefined
|
Avec l’attribut
protected
, nouveau en ActionScript 3.0, une propriété n’est visible qu’à partir de sa propre classe ou d’une sous-classe de celle-ci. Autrement dit, une propriété déclarée protected n’est disponible qu’à partir de sa propre classe ou des classes qui lui sont inférieures dans sa hiérarchie d’héritage, que la sous-classe se trouve dans le même package ou dans un autre.
Pour les programmeurs qui connaissent ActionScript 2.0, cette fonctionnalité est semblable à l’attribut
private
de ce langage. L’attribut
protected
d’ActionScript 3.0 est également semblable à l’attribut
protected
de Java, à la différence près que la version de Java autorise également l’accès à partir d’un même package. L’attribut
protected
est utile pour créer une variable ou une méthode nécessaire aux sous-classes, mais qui ne doit pas être visible à partir du code extérieur à la hiérarchie d’héritage.
Avec l’attribut
interne
qui apparaît avec ActionScript 3.0, une propriété n’est visible qu’à partir de son propre package. Il s’agit de l’attribut par défaut pour du code dans un package et il s’applique à toute propriété dépourvue de l’un quelconque des attributs suivants :
L’attribut
internal
est semblable au contrôle d’accès par défaut de Java quoiqu’en Java il n’existe pas de nom explicite pour ce niveau d’accès ; il ne peut être obtenu que par l’omission de tout autre modificateur d’accès. Avec l’attribut
internal
, qui apparaît avec ActionScript 3.0, il est possible d’indiquer explicitement votre intention de ne rendre une propriété visible qu’à partir de son propre package.
Attribut static
L’attribut
static
, qui peut être utilisé avec des propriétés déclarées à l’aide des mots-clés
var
,
const
ou
function
, vous permet d’associer une propriété à la classe elle-même plutôt qu’à ses occurrences. Le code externe à cette classe doit appeler les propriétés statiques à l’aide du nom de la classe et non pas à partir du nom d’une occurrence.
Les sous-classes n’héritent pas des propriétés statiques ; ces dernières font partie de leur chaîne de portée. En d’autres termes, dans le corps d’une sous-classe, une variable ou une méthode statique peut être utilisée sans faire référence à la classe dans laquelle elle a été définie.
Attributs d’espace de noms définis par l’utilisateur
Comme solution de rechange aux attributs de contrôle d’accès prédéfinis, vous pouvez créer un espace de noms personnalisé pour l’utiliser comme attribut. Il ne peut exister qu’un seul attribut d’espace de noms par définition et vous ne pouvez pas associer cet attribut à tout attribut de contrôle d’accès (
public
,
private
,
protected
,
internal
).
Variables
Pour déclarer une variable, utilisez les mots-clés
var
ou
const
. Les variables déclarées avec le mot-clé
var
sont susceptibles de changer de valeur plusieurs fois au cours de l’exécution d’un script. Les variables déclarées à l’aide du mot-clé
const
sont appelées des
constantes
et on ne peut leur attribuer une valeur qu’une seule fois. Une erreur survient lors d’une tentative d’attribution d’une nouvelle valeur à une constante initialisée.
Variables statiques
Les variables statiques sont déclarées à l’aide de l’association du mot-clé
static
et de l’instruction
var
ou
const
. Les variables statiques sont affectées à une classe, plutôt qu’à une occurrence de classe. Elles permettent de stocker et de partager des informations propres à une classe entière d’objets. Par exemple, une variable statique permet d’enregistrer le nombre de fois où une classe a été instanciée ou bien le nombre maximal d’occurrences autorisées pour une classe.
L’exemple ci-dessous crée une variable
totalCount
qui permet d’enregistrer le nombre total d’instanciations d’une classe et une constante
MAX_NUM
dont la valeur est le nombre maximum d’instanciations autorisées. Les variables
totalCount
et
MAX_NUM
sont statiques car elles contiennent des valeurs qui s’appliquent à la classe elle-même, plutôt qu’à une occurrence particulière.
class StaticVars
{
public static var totalCount:int = 0;
public static const MAX_NUM:uint = 16;
}
Un code extérieur à la classe StaticVars, ainsi que toutes ses sous-classes, ne peuvent faire référence aux propriétés
totalCount
et
MAX_NUM
que par le biais de la classe elle-même. Par exemple, le code suivant fonctionne :
trace(StaticVars.totalCount); // output: 0
trace(StaticVars.MAX_NUM); // output: 16
Comme il est impossible d’accéder à des variables statiques par une occurrence de la classe, le code suivant renvoie des erreurs :
var myStaticVars:StaticVars = new StaticVars();
trace(myStaticVars.totalCount); // error
trace(myStaticVars.MAX_NUM); // error
Les variables qui sont déclarées avec les deux mots-clés
static
et
const
doivent être initialisées en même temps lors de la déclaration de la constante, tout comme la classe StaticVars le fait pour
MAX_NUM
. Il est impossible d’attribuer une valeur à
MAX_NUM
au sein du constructeur ou d’une méthode d’occurrence. Le code suivant génère une erreur, car ce n’est pas une façon valide d’initialiser une constante statique :
// !! Error to initialize static constant this way
class StaticVars2
{
public static const UNIQUESORT:uint;
function initializeStatic():void
{
UNIQUESORT = 16;
}
}
Variables d’occurrence
Les variables d’occurrence contiennent des propriétés déclarées à l’aide des mots-clés
var
et
const
, mais sans le mot-clé
static
. Les variables d’occurrence, qui sont associées à des occurrences de classe plutôt qu’à la classe elle-même, sont utiles pour conserver des valeurs spécifiques à une occurrence. Par exemple, la classe Array dispose d’une propriété d’occurrence appelée
length
qui conserve le nombre d’éléments du tableau appartenant à une occurrence particulière de la classe Array.
Qu’elles soient déclarées avec le mot-clé
var
ou
const
, les variables d’occurrence ne peuvent pas être redéfinies dans une sous-classe. Il est toutefois possible d’obtenir un effet similaire à la redéfinition de variables, en redéfinissant des méthodes de lecture et de définition.
Méthodes
Les méthodes sont des fonctions associées à la définition d’une classe. Dès la création d’une occurrence de la classe, une méthode est liée à cette occurrence. Contrairement à une fonction déclarée hors d’une classe, une méthode ne peut pas être utilisée séparément de l’occurrence à laquelle elle est associée.
Les méthodes sont définies à l’aide du mot-clé
function
. Comme toute propriété de classe, vous pouvez appliquer n’importe quel attribut de propriété de classe aux méthodes, qu’elles soient privées, protégées, publiques, internes ou statiques, ainsi qu’à un espace de noms personnalisé. Vous pouvez utiliser une instruction function telle que :
public function sampleFunction():String {}
Vous pouvez aussi utiliser une variable à laquelle vous attribuez une expression de fonction, comme ci-dessous :
public var sampleFunction:Function = function () {}
Dans la plupart des cas, il est préférable d’utiliser une instruction function plutôt qu’une expression de fonction pour les raisons suivantes :
-
Les instructions function sont plus concises et plus faciles à lire.
-
Elles vous permettent d’utiliser les mots-clés
override
et
final
.
-
Les instructions function créent une liaison plus robuste entre l’identifiant (le nom de la fonction) et le code dans le corps de la méthode. Comme la valeur d’une variable peut être modifiée par une instruction assignment, le lien entre une variable et son expression de fonction peut être rompu à tout moment. Bien qu’il soit possible de résoudre ce problème en déclarant la variable avec
const
au lieu de
var
, cette technique n’est pas recommandée car elle rend le code difficilement lisible et empêche d’utiliser les mots-clés
override
et
final
.
Il existe toutefois un cas dans lequel une expression de fonction doit être utilisée : si vous choisissez d’affecter une fonction à l’objet prototype.
Méthodes constructeur
Les méthodes constructeur, parfois appelées simplement
constructeurs
, sont des fonctions qui portent le nom de la classe dans laquelle elles sont définies. Tout code qui figure dans une méthode constructeur est exécuté toutes les fois qu’une occurrence de la classe est créée à l’aide du mot-clé
new
. Par exemple, le code suivant définit une classe simple appelée Example qui contient une propriété unique appelée
status
. La valeur initiale de la variable
status
est fixée dans la fonction constructeur.
class Example
{
public var status:String;
public function Example()
{
status = "initialized";
}
}
var myExample:Example = new Example();
trace(myExample.status); // output: initialized
Les méthodes constructeur ne peuvent être que publiques, mais l’utilisation de l’attribut
public
est facultative. Il est impossible d’utiliser l’un des autres spécificateurs de contrôle d’accès, y compris
private
,
protected
ou
internal
avec un constructeur. De même qu’il est impossible d’utiliser non plus, avec un constructeur, un espace de noms défini par l’utilisateur.
Un constructeur peut appeler explicitement le constructeur de sa superclasse directe, à l’aide de l’instruction
super()
. Si le constructeur de la superclasse n’est pas explicitement appelé, le compilateur insère automatiquement un appel devant la première instruction dans le corps du constructeur. Vous pouvez aussi appeler des méthodes de la superclasse à l’aide du préfixe
super
en référence à la superclasse. Si vous décidez d’utiliser à la fois
super()
et
super
dans le corps du même constructeur, veillez à appeler
super()
en premier. Sinon, la référence
super
n’a pas le comportement prévu. Le constructeur
super()
devrait également être appelé avant toute instruction
throw
ou
return
.
L’exemple suivant décrit ce qui se passe si vous tentez d’utiliser la référence
super
avant d’appeler le constructeur
super()
. Une nouvelle classe, ExampleEx, étend la classe Example. Le constructeur ExampleEx tente d’accéder à la variable d’état définie dans sa super classe, mais avant un appel à
super()
. L’instruction
trace()
du constructeur ExampleEx produit la valeur
null
car la variable
status
n’est pas disponible tant que le constructeur
super()
n’a pas été exécuté.
class ExampleEx extends Example
{
public function ExampleEx()
{
trace(super.status);
super();
}
}
var mySample:ExampleEx = new ExampleEx(); // output: null
Bien que l’utilisation de l’instruction
return
au sein d’un constructeur soit autorisée, il n’est pas permis de renvoyer une valeur. En d’autres termes, aucune expression ou valeur ne peut être associée à l’instruction
return
. Par conséquent, les méthodes constructeur ne sont pas autorisées à renvoyer des valeurs, ce qui signifie qu’aucun type de valeur renvoyée ne peut être spécifié.
Si vous ne définissez pas de méthode constructeur dans la classe, le compilateur crée automatiquement un constructeur vide. Si la classe en étend une autre, le compilateur insère un appel
super()
dans le constructeur qu’il génère.
Méthodes statiques
Les méthodes statiques, également appelées parfois
méthodes de classe
, sont déclarées avec le mot-clé
static
. Les méthodes statiques sont affectées à une classe plutôt qu’à une occurrence de classe. Elles permettent d’encapsuler des fonctionnalités qui ont une portée plus étendue que l’état d’une occurrence individuelle. Comme les méthodes statiques sont associées à l’intégralité d’une classe, on peut accéder à des méthodes statiques uniquement par une classe et pas du tout par une occurrence de classe.
Les méthodes statiques permettent d’encapsuler des fonctionnalités qui ne se bornent pas à la modification d’état des occurrences de classe. Autrement dit, une méthode devrait être statique si elle offre des fonctionnalités qui n’affectent pas directement la valeur d’une occurrence de classe. Par exemple, la classe Date possède une méthode statique appelée
parse()
qui reçoit une chaîne et la convertit en nombre. La méthode est statique parce qu’elle n’affecte pas une occurrence individuelle de sa classe. La méthode
parse()
, reçoit une chaîne représentant une valeur de date, l’analyse et renvoie un nombre dans un format compatible avec la représentation interne d’un objet Date. Cette méthode n’est pas une méthode d’occurrence, puisqu’il n’y aurait aucun intérêt à l’appliquer à une occurrence de la classe Date.
Comparons la méthode statique
parse()
à l’une des méthodes d’occurrence de la classe Date, comme
getMonth()
. La méthode
getMonth()
est une méthode d’occurrence parce qu’elle agit directement sur la valeur d’une occurrence en récupérant un composant spécifique, le mois, d’une occurrence de Date.
Comme les méthodes statiques ne sont pas liées à des occurrences individuelles, vous ne pouvez pas utiliser les mots-clés
this
ou
super
dans le corps d’une méthode statique. Les deux références
this
et
super
n’ont de sens que dans le contexte d’une méthode d’occurrence.
Contrairement à d’autres langages de programmation basés sur des classes, les méthodes statiques en ActionScript 3.0 ne sont pas héritées.
Méthodes d’occurrence
Les méthodes d’occurrence sont déclarées sans le mot-clé
static
. Les méthodes d’occurrence, qui sont affectées aux occurrences d’une classe et non pas à la classe elle-même, permettent d’implémenter des fonctionnalités qui affectent des occurrences individuelles d’une classe. Par exemple, la classe Array contient une méthode d’occurrence appelée
sort()
qui opère directement sur des occurrences Array.
Dans le corps d’une méthode d’occurrence, les variables statiques et d’occurrence sont de même portée ; ce qui signifie que les variables définies dans la même classe peuvent être référencées à l’aide d’un identificateur simple. Par exemple, la classe suivante, CustomArray, étend la classe Array. La classe CustomArray définit une variable statique appelée
arrayCountTotal
destinée à contenir le nombre total d’occurrences de la classe, une variable d’occurrence appelée
arrayNumber
qui enregistre l’ordre dans lequel les occurrences ont été créées et une méthode d’occurrence appelée
getPosition()
qui renvoie les valeurs de ces variables.
public class CustomArray extends Array
{
public static var arrayCountTotal:int = 0;
public var arrayNumber:int;
public function CustomArray()
{
arrayNumber = ++arrayCountTotal;
}
public function getArrayPosition():String
{
return ("Array " + arrayNumber + " of " + arrayCountTotal);
}
}
Pour accéder à la variable statique
arrayCountTotal
, du code externe à cette classe doit passer par l’objet class utilisant
CustomArray.arrayCountTotal
; mais le code qui réside dans le corps de la méthode
getPosition()
peut faire référence directement à la variable statique
arrayCountTotal
. C’est également le cas pour les variables statiques dans les superclasses. Bien que les propriétés statiques ne soient pas héritées en ActionScript 3.0, les propriétés statiques des superclasses sont dans la portée. Par exemple, la classe Array possède quelques variables statiques, dont l’une est une constante appelée
DESCENDING
. Le code qui réside dans une sous-classe d’Array peut accéder à la constante statique
DESCENDING
à l’aide d’un identifiant simple :
public class CustomArray extends Array
{
public function testStatic():void
{
trace(DESCENDING); // output: 2
}
}
La valeur de la référence
this
dans le corps d’une méthode d’occurrence est une référence à l’occurrence à laquelle la méthode est affectée. Le code suivant montre que la référence
this
pointe sur l’occurrence qui contient la méthode :
class ThisTest
{
function thisValue():ThisTest
{
return this;
}
}
var myTest:ThisTest = new ThisTest();
trace(myTest.thisValue() == myTest); // output: true
Il est possible de contrôler l’héritage des méthodes d’occurrence à l’aide des mots-clés
override
et
final
. Vous pouvez utiliser l’attribut
override
pour redéfinir une méthode héritée et l’attribut
final
pour empêcher les sous-classes de redéfinir une méthode.
Méthodes accesseur get et set
Les fonctions d’accesseur de lecture et de définition, appelées aussi accesseurs
Get
et
Set
, vous permettent de suivre les principes de programmation sur le masquage et l’encapsulation des informations tout en offrant une interface de programmation conviviale pour les classes que vous créez. Les fonctions de lecture et de définition (get et set) permettent de garder privées les propriétés d’une classe. Par contre, elles permettent à des utilisateurs de votre classe d’accéder à ces propriétés comme s’ils accédaient à une variable de classe au lieu d’appeler une méthode de classe.
L’avantage de cette approche est qu’elle permet d’éviter les fonctions d’accesseur traditionnelles aux noms compliqués, comme
getPropertyName()
et
setPropertyName()
. Leur autre avantage est qu’elles évitent d’avoir deux fonctions exposées publiquement pour chaque propriété accessible en lecture et en écriture.
Dans l’exemple suivant, la classe appelée GetSet, possède des fonctions accesseurs de lecture et de définition appelées
publicAccess()
qui permettent d’accéder à la variable privée appelée
privateProperty
:
class GetSet
{
private var privateProperty:String;
public function get publicAccess():String
{
return privateProperty;
}
public function set publicAccess(setValue:String):void
{
privateProperty = setValue;
}
}
Si vous tentez d’accéder directement à la propriété
privateProperty
, une erreur se produit :
var myGetSet:GetSet = new GetSet();
trace(myGetSet.privateProperty); // error occurs
En revanche, si vous utilisez la classe GetSet, vous faites appel à ce qui paraît être une propriété appelée
publicAccess
, mais qui correspond, en fait, à une paire de fonctions accesseurs de lecture et de définition intervenant sur la propriété privée appelée
privateProperty
. L’exemple suivant instancie la classe GetSet, puis définit la valeur de la propriété
privateProperty
à l’aide de l’accesseur public appelé
publicAccess
:
var myGetSet:GetSet = new GetSet();
trace(myGetSet.publicAccess); // output: null
myGetSet.publicAccess = "hello";
trace(myGetSet.publicAccess); // output: hello
Les fonctions d’accesseur Get et Set permettent également de redéfinir des propriétés héritées d’une superclasse, ce qui n’est pas possible avec des variables régulières membres de classes. Les variables des membres de la classe qui sont déclarées à l’aide du mot-clé
var
ne peuvent pas être redéfinies dans une sous-classe. Toutefois, cette restriction ne concerne pas les propriétés créées à l’aide des fonctions d’accesseur Get et Set. Vous pouvez utiliser l’attribut
override
sur des fonctions d’accesseur Get et Set héritées d’une superclasse.
Méthodes liées
Une méthode liée, parfois appelée
fermeture de méthode
, est tout simplement une méthode extraite de son occurrence. On peut citer comme exemples les méthodes passées en arguments à une fonction ou renvoyées comme valeurs par une fonction. La méthode liée, qui est une nouveauté d’ActionScript 3.0, est semblable à une fermeture de fonction dans la mesure où elle conserve son environnement lexical, même après avoir été extraite de son occurrence. Toutefois, la différence entre une méthode liée et une fermeture de fonction réside dans le fait que la référence
this
d’une méthode liée reste liée à l’occurrence qui implémente cette méthode. Autrement dit, la référence
this
d’une méthode liée pointe toujours sur l’objet original qui a implémenté la méthode. Pour les fermetures de fonction, la référence
this
est générique, ce qui signifie qu’elle pointe sur l’objet auquel est associée la fonction lorsqu’elle est appelée.
Il est important de comprendre les méthodes liées pour utiliser le mot-clé
this
à bon escient. N’oubliez pas que
this
représente une référence à l’objet parent d’une méthode. La plupart des programmeurs en ActionScript s’attendent à ce que le mot-clé
this
représente toujours l’objet ou la classe qui contient la définition d’une méthode. Ce n’est pas toujours le cas sans méthode liée. Par exemple, dans les versions précédentes d’ActionScript, la référence
this
ne pointait pas toujours sur l’occurrence qui implémentait la méthode. En ActionScript 2.0, lorsque les méthodes sont extraites d’une occurrence, non seulement la référence
this
n’est pas liée à l’occurrence originale, mais les variables et les méthodes de la classe de cette occurrence ne sont pas disponibles. Toutefois, ce problème n’existe plus avec ActionScript 3.0, car les méthodes liées sont automatiquement créées lorsque la méthode est passée en paramètre. Avec les méthodes liées, le mot-clé
this
fait toujours référence à l’objet ou à la classe dans laquelle la méthode est définie.
Le code suivant définit une classe appelée ThisTest, qui contient une méthode appelée
foo()
définissant la méthode liée et une méthode appelée
bar()
qui renvoie cette méthode liée. Le code extérieur à la classe crée une occurrence de la classe ThisTest, appelle la méthode
bar()
et enregistre la valeur à renvoyer dans la variable
myFunc
.
class ThisTest
{
private var num:Number = 3;
function foo():void // bound method defined
{
trace("foo's this: " + this);
trace("num: " + num);
}
function bar():Function
{
return foo; // bound method returned
}
}
var myTest:ThisTest = new ThisTest();
var myFunc:Function = myTest.bar();
trace(this); // output: [object global]
myFunc();
/* output:
foo's this: [object ThisTest]
output: num: 3 */
Les deux dernières lignes de code montrent que la référence
this
dans la méthode liée
foo()
pointe encore sur une occurrence de la classe ThisTest, bien que la référence
this
de la ligne précédente pointe sur l’objet global. De plus, la méthode liée, stockée dans la variable
myFunc
, peut encore accéder aux variables membres de la classe ThisTest. Si ce code est exécuté en ActionScript 2.0, les références
this
seront identiques et la variable
num
sera
undefined
.
Les gestionnaires d’événement constituent un domaine dans lequel l’ajout des méthodes liées est le plus notable, car la méthode
addEventListener()
nécessite de transmettre une fonction ou une méthode en argument.
Enumérations et classes
Les
énumérations
sont des types de données que vous pouvez créer pour encapsuler un petit ensemble de valeur. Contrairement à C++ avec le mot-clé
enum
et à Java avec l’interface d’énumération, ActionScript 3.0 ne dispose pas d’un mécanisme d’énumération spécifique. Il est toutefois possible de créer des énumérations à l’aide de classes et de constantes statiques. Par exemple, en ActionScript 3.0, la classe PrintJob utilise une énumération appelée PrintJobOrientation pour stocker les valeurs
"landscape"
et
"portrait"
, comme l’indique le code ci-dessous :
public final class PrintJobOrientation
{
public static const LANDSCAPE:String = "landscape";
public static const PORTRAIT:String = "portrait";
}
Par convention, une classe d’énumération est déclarée avec l’attribut
final
, car il n’est pas nécessaire d’étendre cette classe. Cette classe étant composée uniquement de membres statiques, il est impossible d’en créer des occurrences. En effet, on accède aux valeurs de l’énumération directement par l’objet classe, comme le montre l’extrait de code suivant :
var pj:PrintJob = new PrintJob();
if(pj.start())
{
if (pj.orientation == PrintJobOrientation.PORTRAIT)
{
...
}
...
}
Toutes les classes d’énumération d’ActionScript 3.0 contiennent uniquement des variables de type String, int ou uint. Le fait que les fautes de frappe sont plus faciles à détecter avec les énumérations présente un grand avantage par rapport à des chaînes littérales ou des nombres. Si vous faites une erreur dans le nom d’une énumération, le compilateur ActionScript génère une erreur. Si vous utilisez des valeurs littérales, le compilateur acceptera un nom mal épelé ou un chiffre erroné. Dans l’exemple ci-dessus, le compilateur génère une erreur si le nom de la constante d’énumération est incorrect, comme dans l’extrait suivant :
if (pj.orientation == PrintJobOrientation.PORTRAI) // compiler error
Toutefois, le compilateur ne génère pas d’erreur si vous faites une faute de frappe dans le nom d’une chaîne littérale :
if (pj.orientation == "portrai") // no compiler error
Une autre technique de création d’énumérations consiste à créer une classe séparée avec des propriétés statiques pour l’énumération. Toutefois, cette technique est différente dans la mesure où chacune des propriétés statiques contient une occurrence de la classe plutôt qu’une valeur chaîne ou un entier. Par exemple, le code suivant crée une classe d’énumération pour les jours de la semaine :
public final class Day
{
public static const MONDAY:Day = new Day();
public static const TUESDAY:Day = new Day();
public static const WEDNESDAY:Day = new Day();
public static const THURSDAY:Day = new Day();
public static const FRIDAY:Day = new Day();
public static const SATURDAY:Day = new Day();
public static const SUNDAY:Day = new Day();
}
Cette technique n’est pas utilisée par ActionScript 3.0, mais de nombreux développeurs y ont recours car elle permet d’obtenir un meilleur type de vérification. Par exemple, une méthode qui renvoie une valeur d’énumération peut restreindre la valeur renvoyée au type de données de l’énumération. Le code suivant illustre non seulement une fonction qui renvoie un jour de la semaine, mais aussi un appel de fonction qui utilise le type énumération comme annotation de type :
function getDay():Day
{
var date:Date = new Date();
var retDay:Day;
switch (date.day)
{
case 0:
retDay = Day.MONDAY;
break;
case 1:
retDay = Day.TUESDAY;
break;
case 2:
retDay = Day.WEDNESDAY;
break;
case 3:
retDay = Day.THURSDAY;
break;
case 4:
retDay = Day.FRIDAY;
break;
case 5:
retDay = Day.SATURDAY;
break;
case 6:
retDay = Day.SUNDAY;
break;
}
return retDay;
}
var dayOfWeek:Day = getDay();
Il est également possible d’améliorer la classe Day afin qu’elle associe un entier à chaque jour de la semaine et comporte une méthode
toString()
renvoyant une représentation du jour sous forme de chaîne.
Classes des éléments incorporés
ActionScript 3.0 utilise des classes spéciales, appelées
classes des éléments incorporés
, pour représenter les actifs incorporés. Un
élément incorporé
est un élément (son, image ou police) qui est incorporé au fichier SWF lors de la compilation. Contrairement au chargement dynamique, l’incorporation des actifs les rend disponibles immédiatement lors de l’exécution ; mais cette méthode augmente la taille des fichiers SWF.
Utilisation de classes d’actifs incorporés dans Flash Professional
Pour incorporer un élément, placez-le d’abord dans la bibliothèque d’un fichier FLA. Utilisez ensuite la propriété de liaison de l’élément pour fournir un nom à la classe de l’élément incorporé. S’il n’existe pas de classe de ce nom dans le chemin de classe indiqué, une classe est automatiquement créée. Vous pouvez alors créer une occurrence de la classe d’éléments incorporés et utiliser les propriétés et méthodes définies ou héritées par cette classe. Par exemple, le code suivant permet de lire un son intégré et lié à une classe d’éléments incorporés appelée PianoMusic :
var piano:PianoMusic = new PianoMusic();
var sndChannel:SoundChannel = piano.play();
Pour incorporer des actifs dans un projet Flash Professional, vous pouvez aussi utiliser la balise de métadonnées
[Embed]
(voir ci-après). Dans ce cas, Flash Professional fait appel au compilateur Flex, et non à son propre compilateur, pour compiler le projet.
Utilisation de classe d’actifs intégrés à l’aide du compilateur Flex
Lorsque vous utilisez le compilateur Flex, servez-vous de la balise de métadonnées
[Embed]
pour incorporer un actif dans le code ActionScript. Placez l’actif dans le dossier source principal ou dans un autre dossier qui se trouve dans le chemin de création. Lorsque le compilateur Flex trouve une balise de métadonnées Embed, il crée la classe d’actifs intégrés pour vous. Il est possible d’accéder à la classe par une variable de type de données Class que l’on déclare immédiatement après la balise de métadonnées
[Embed]
. Par exemple, le code ci-dessous intègre un son appelé sound1.mp3. Il utilise une variable appelée
soundCls
pour enregistrer une référence à la classe de l’élément intégré associé à ce son. L’exemple crée alors une occurrence de la classe de l’élément intégré et appelle la méthode
play()
sur cette occurrence :
package
{
import flash.display.Sprite;
import flash.media.SoundChannel;
import mx.core.SoundAsset;
public class SoundAssetExample extends Sprite
{
[Embed(source="sound1.mp3")]
public var soundCls:Class;
public function SoundAssetExample()
{
var mySound:SoundAsset = new soundCls() as SoundAsset;
var sndChannel:SoundChannel = mySound.play();
}
}
}
Adobe Flash Builder
Pour utiliser la balise de métadonnées
[Embed]
dans un projet ActionScript Flash Builder, importez les classes nécessaires depuis la structure Flex. Par exemple, pour incorporer des sons, importez la classe mx.core.SoundAsset. Pour utiliser la structure Flex, ajoutez le fichier framework.swc à votre chemin de création ActionScript. La taille du fichier SWF va alors augmenter.
Adobe Flex
Dans Flex, vous pouvez aussi intégrer un actif à l’aide de la directive
@Embed()
dans une définition de balise MXML.
|
|
|