Classes
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 classeEn 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 classeActionScript 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 classeLe 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 classeDans 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 Adobe ActionScript 3.0 Reference for the Adobe Flash Platform : 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èsActionScript 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 staticL’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’utilisateurComme 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).
VariablesPour 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 statiquesLes 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’occurrenceLes 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éthodesLes 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 constructeurLes 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 statiquesLes 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’occurrenceLes 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 setLes 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éesUne 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 classesLes é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ésActionScript 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 ProfessionalPour 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 FlexLorsque 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 BuilderPour 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 FlexDans Flex, vous pouvez aussi intégrer un actif à l’aide de la directive @Embed() dans une définition de balise MXML.
|
|