Documentation Flash CS3 |
|||
| Programmation avec ActionScript 3.0 > Syntaxe et langage ActionScript > Packages et espaces de nom > Espaces de noms | |||
Les espaces de nom vous permettent de contrôler la visibilité des propriétés et des méthodes que vous créez. Considérez les spécificateurs de contrôle d'accès public, private, protected, et internal comme des espaces de nom intégrés. Si ces spécificateurs de contrôle d'accès prédéfinis ne répondent pas à vos besoins, vous pouvez créer vos propres espaces de nom.
Si vous avez l'habitude d'utiliser des espaces de nom XML, cette section ne vous fournira pas de nouvelles informations, bien que la syntaxe et les détails de l'implémentation d'ActionScript soient légèrement différents de ceux d'XML. Si vous n'avez jamais travaillé avec des espaces de nom, le concept est simple, mais l'implémentation possède une terminologie particulière que vous devrez apprendre.
Pour comprendre comment fonctionnent les espaces de nom, il convient de savoir que le nom d'une propriété ou d'une méthode contient deux parties : un identifiant et un espace de nom. L'identifiant est ce que vous considérez généralement comme un nom. Par exemple, les identifiants dans la définition de classe suivante sont sampleGreeting et sampleFunction():
class SampleCode
{
var sampleGreeting:String;
function sampleFunction () {
trace(sampleGreeting + " from sampleFunction()");
}
}
Lorsque les définitions ne sont pas précédées d'un attribut d'espace de nom, leurs noms sont qualifiés par l'espace de nom internal par défaut, ce qui signifie qu'ils sont visibles uniquement aux appelants du même package. Si le compilateur est défini sur le mode strict, il génère un avertissement indiquant que l'espace de nom internal s'applique à tout identifiant sans attribut d'espace de nom. Pour vérifier qu'un identifiant est disponible partout, vous devez spécifiquement faire précéder le nom de l'identifiant de l'attribut public. Dans l'exemple de code précédent, sampleGreeting et sampleFunction() ont une valeur d'espace de nom d'internal.
Vous devez suivre trois étapes de base lorsque vous utilisez des espaces de nom. Premièrement, vous devez définir l'espace de nom à l'aide du mot-clé namespace. Par exemple, le code suivant définit l'espace de nom version1 :
namespace version1;
Deuxièmement, vous appliquez votre espace de nom en l'utilisant à la place d'un spécificateur de contrôle d'accès dans une déclaration de méthode ou de propriété. L'exemple suivant place une fonction appelée myFunction() dans l'espace de nom version1 :
version1 function myFunction() {}
Troisièmement, une fois que vous avez appliqué l'espace de nom, vous pouvez le référencer à l'aide de la directive use ou en qualifiant le nom d'un identifiant avec un espace de nom. L'exemple suivant fait référence à la fonction myFunction() à l'aide de la directive use :
use namespace version1; myFunction();
Vous pouvez également utiliser un nom qualifié pour référencer la fonction myFunction(), comme l'indique l'exemple suivant :
version1::myFunction();
Les espaces de nom contiennent une valeur, l'URI (Uniform Resource Identifier), parfois appelée nom d'espace de nom. Un URI vous permet de vérifier que votre définition d'espace de nom est unique.
Vous créez un espace de nom en déclarant une définition d'espace de nom de deux façons différentes. Vous pouvez soit définir un espace de nom avec un URI explicite, comme vous définiriez un espace de nom XML, soit omettre l'URI. L'exemple suivant indique comment un espace de nom peut être défini à l'aide d'un URI :
namespace flash_proxy = "http://www.adobe.com/flash/proxy";
L'URI sert de chaîne d'identification unique pour cet espace de nom. Si vous omettez l'URI, comme dans l'exemple suivant, le compilateur crée une chaîne d'identification interne unique à la place de l'URI. Vous n'avez pas accès à cette chaîne d'identification interne.
namespace flash_proxy;
Une fois que vous avez défini un espace de nom (avec ou sans URI), vous ne pouvez pas le redéfinir dans le même domaine. Une tentative de définition d'un espace de nom ayant été défini dans le même domaine génère une erreur du compilateur.
Si un espace de nom est défini dans un package ou une classe, il risque de ne pas être visible au code externe à ce package ou à cette classe, à moins que vous utilisez le spécificateur de contrôle d'accès approprié. Par exemple, le code suivant indique l'espace de nom flash_proxy défini dans le package flash.utils. Dans l'exemple suivant, l'absence de spécificateur de contrôle d'accès signifie que l'espace de nom flash_proxy est visible uniquement au code dans le package flash.utils et non au code externe au package :
package flash.utils
{
namespace flash_proxy;
}
Le code suivant utilise l'attribut public pour rendre l'espace de nom flash_proxy visible au code externe au package :
package flash.utils
{
public namespace flash_proxy;
}
Appliquer un espace de nom signifie placer une définition dans un espace de nom. Les définitions que vous pouvez placer dans des espaces de nom peuvent être des fonctions, des variables et des constantes (vous ne pouvez pas placer une classe dans un espace de nom personnalisé).
Supposez, par exemple, que vous avez une fonction déclarée à l'aide de l'espace de nom de contrôle d'accès public. L'utilisation de l'attribut public dans une définition de fonction place la fonction dans l'espace de nom public et rend la fonction visible à tout le code. Une fois que vous avez défini un espace de nom, vous pouvez l'utiliser de la même façon que vous utiliseriez l'attribut public, et la définition est disponible au code pouvant référencer votre espace de nom personnalisé. Par exemple, si vous définissez un espace de nom example1, vous pouvez ajouter une méthode appelée myFunction() à l'aide de example1 comme attribut, tel que l'indique l'exemple suivant :
namespace example1;
class someClass
{
example1 myFunction() {}
}
Déclarer la méthode myFunction() à l'aide de l'espace de nom example1 comme attribut signifie que la méthode appartient à l'espace de nom example1.
Tenez compte des points suivants lorsque vous appliquez des espaces de nom :
public, private, protected, ou internal si vous appliquez votre espace de nom.Il est inutile de référencer explicitement un espace de nom lorsque vous utilisez une méthode ou une propriété déclarée avec l'un des espaces de nom de contrôle d'accès (public, private, protected et internal, par exemple). En effet, l'accès à ces espaces de nom spéciaux dépend du contexte. Par exemple, les définitions placées dans l'espace de nom private sont automatiquement disponibles pour le code dans la même classe. Pour les espaces de nom que vous définissez, cependant, le contexte ne compte pas. Pour utiliser une méthode ou une propriété que vous avez placée dans un espace de nom personnalisé, vous devez référencer l'espace de nom.
Vous pouvez référencer des espaces de nom avec la directive use namespace ou qualifier le nom avec l'espace de nom à l'aide du ponctuateur de qualificatif de nom (::). Le fait de référencer un espace de nom avec la directive use namespace « ouvre » l'espace de nom, ce qui permet de l'appliquer à n'importe quel identifiant non qualifié. Par exemple, si vous avez défini l'espace de nom example1, vous pouvez accéder aux noms dans cet espace de nom en utilisant use namespace example1:
use namespace example1; myFunction();
Vous pouvez ouvrir plusieurs espaces de nom simultanément. Une fois que vous avez ouvert un espace de nom avec use namespace, il reste ouvert dans le bloc de code dans lequel il a été ouvert. Il n'existe aucun moyen pour fermer explicitement un espace de nom.
Néanmoins, le fait d'avoir plusieurs espaces de nom ouverts augmente la probabilité que des conflits de noms se produisent. Si vous préférez ne pas ouvrir d'espace de nom, vous pouvez éviter la directive use namespace en qualifiant le nom de la propriété ou de la méthode avec l'espace de nom et le ponctuateur de qualificatif de nom. Par exemple, le code suivant indique comment vous pouvez qualifier le nom myFunction() avec l'espace de nom example1 :
example1::myFunction();
Vous pouvez trouver un exemple concret d'espace de nom utilisé pour empêcher les conflits de nom dans la classe flash.utils.Proxy qui fait partie de l'API de Flash Player. La classe Proxy, qui remplace la propriété Object.__resolve d'ActionScript 2.0, vous permet d'intercepter des références vers des méthodes ou des propriétés non définies avant qu'une erreur se produise. Toutes les méthodes de la classe Proxy se trouvent dans l'espace de nom flash_proxy afin d'empêcher les conflits de noms.
Pour mieux comprendre comment l'espace de nom flash_proxy est utilisé, vous devez savoir comment utiliser la classe Proxy. La fonctionnalité de la classe Proxy est disponible uniquement aux classes qui héritent d'elle. En d'autres termes, si vous souhaitez utiliser les méthodes de la classe Proxy d'un objet, la définition de classe de l'objet doit étendre la classe Proxy. Par exemple, si vous souhaitez intercepter des tentatives d'appel d'une méthode non définie, vous devez étendre la classe Proxy puis remplacer la méthode callProperty() de la classe Proxy.
L'implémentation des espaces de nom est généralement un processus en trois étapes (définition, application et référence d'un espace de nom). Etant donné que vous n'appelez jamais explicitement une méthode de la classe Proxy, cependant, l'espace de nom flash_proxy est défini et appliqué uniquement, jamais référencé. L'API de Flash Player définit l'espace de nom flash_proxy et l'applique dans la classe Proxy. Votre code doit uniquement appliquer l'espace de nom flash_proxy à des classes qui étendent la classe Proxy.
L'espace de nom flash_proxy est défini dans le package flash.utils d'une manière semblable à la suivante :
package flash.utils
{
public namespace flash_proxy;
}
L'espace de nom est appliqué aux méthodes de la classe Proxy comme indiqué dans l'extrait suivant issu de la classe Proxy :
public class Proxy
{
flash_proxy function callProperty(name:*, ... rest):*
flash_proxy function deleteProperty(name:*):Boolean
...
}
Comme l'indique le code suivant, vous devez d'abord importer la classe Proxy et l'espace de nom flash_proxy. Vous devez ensuite déclarer votre classe de façon à ce qu'elle étende la classe Proxy (vous devez également ajouter l'attribut dynamic si vous compilez en mode strict). Lorsque vous remplacez la méthode callProperty(), vous devez utiliser l'espace de nom flash_proxy.
package
{
import flash.utils.Proxy;
import flash.utils.flash_proxy;
dynamic class MyProxy extends Proxy
{
flash_proxy override function callProperty(name:*, ...rest):*
{
trace("method call intercepted: " + name);
}
}
}
Si vous créez une instance de la classe MyProxy et appelez une méthode non définie (la méthode testing() appelée dans l'exemple suivant, par exemple), votre objet Proxy intercepte l'appel de méthode et exécute les instructions se trouvant dans la méthode callProperty() remplacée (dans ce cas, une instruction trace() simple).
var mySample:MyProxy = new MyProxy(); mySample.testing(); // appel de méthode intercepté : test
Le fait que les méthodes de la classe Proxy se trouvent dans l'espace de nom flash_proxy présente deux avantages. Premièrement, le fait d'avoir un espace de nom séparé réduit l'encombrement dans l'interface publique des classes qui étendent la classe Proxy (il existe environ douze méthodes dans la classe Proxy que vous pouvez remplacer. Elles ne sont pas conçues pour être appelées directement. Le fait de toutes les placer dans l'espace de nom public peut prêter à confusion). Deuxièmement, le fait d'utiliser l'espace de nom flash_proxy évite les conflits de nom si votre sous-classe Proxy contient des méthodes d'instance avec des noms correspondant à l'une des méthodes de la classe Proxy. Par exemple, vous pouvez nommer l'une de vos méthodes callProperty(). Le code suivant est acceptable car votre version de la méthode callProperty() se trouve dans un espace de nom différent :
dynamic class MyProxy extends Proxy
{
public function callProperty() {}
flash_proxy override function callProperty(name:*, ...rest):*
{
trace("method call intercepted: " + name);
}
}
Vous pouvez également utiliser des espaces de nom pour accéder à des méthodes ou à des propriétés autrement qu'avec les quatre spécificateurs de contrôle d'accès (public, private, internal et protected). Par exemple, vous pouvez avoir des méthodes d'utilitaire éparpillées sur plusieurs packages. Vous souhaitez que ces méthodes soient disponibles pour tous vos packages, mais vous ne souhaitez pas qu'elles soient publiques. Pour cela, vous pouvez créer un espace de nom et l'utiliser comme spécificateur de contrôle d'accès spécial.
L'exemple suivant utilise un espace de nom défini par l'utilisateur pour regrouper deux fonctions se trouvant dans différents packages. En les regroupant dans le même espace de nom, vous pouvez rendre les deux fonctions visibles à une classe ou à un package au moyen d'une seule instruction use namespace.
Cet exemple utilise quatre fichiers pour démontrer la technique. Tous les fichiers doivent se trouver dans votre chemin de classe. Le premier fichier, myInternal.as, sert à définir l'espace de nom myInternal. Etant donné que le fichier se trouve dans un package appelé example, vous devez placer le fichier dans un dossier appelé example. L'espace de nom est marqué comme public pour pouvoir être importé dans d'autres packages.
// myInternal.as dans le dossier example
package example
{
public namespace myInternal = "http://www.adobe.com/2006/actionscript/examples";
}
Le deuxième et le troisième fichiers, Utility.as et Helper.as, définissent les classes qui contiennent des méthodes devant être disponibles pour d'autres packages. La classe Utility se trouve dans le package example.alpha, ce qui signifie que le fichier doit être placé dans un dossier appelé alpha qui est un sous-dossier du dossier example. La classe Helper se trouve dans le package example.beta, ce qui signifie que le fichier doit être placé dans un dossier appelé beta qui est également un sous-dossier du dossier example. Ces deux packages, example.alpha et example.beta, doivent importer l'espace de nom avant de l'utiliser.
// Utility.as dans le dossier example/alpha
package example.alpha
{
import example.myInternal;
public class Utility
{
private static var _taskCounter:int = 0;
public static function someTask()
{
_taskCounter++;
}
myInternal static function get taskCounter():int
{
return _taskCounter;
}
}
}
// Helper.as dans le dossier example/beta
package example.beta
{
import example.myInternal;
public class Helper
{
private static var _timeStamp:Date;
public static function someTask()
{
_timeStamp = new Date();
}
myInternal static function get lastCalled():Date
{
return _timeStamp;
}
}
}
Le quatrième fichier, NamespaceUseCase.as, est la classe de l'application principale et doit être un frère pour le dossier example. Dans Adobe Flash CS3 Professional, cette classe serait utilisée comme classe Document pour le FLA. La classe NamespaceUseCase importe également l'espace de nom myInternal et l'utilise pour appeler deux méthodes statiques qui résident dans les autres packages. L'exemple utilise des méthodes statiques pour simplifier le code uniquement . Les méthodes statiques et d'instance peuvent être placées dans l'espace de nom myInternal.
// NamespaceUseCase.as
package
{
import flash.display.MovieClip;
import example.myInternal; // importation de l'espace de nom
import example.alpha.Utility; // importation de la classe Utility
import example.beta.Helper; // importation de la classe Helper
public class NamespaceUseCase extends MovieClip
{
public function NamespaceUseCase()
{
use namespace myInternal;
Utility.someTask();
Utility.someTask();
trace(Utility.taskCounter); // 2
Helper.someTask();
trace(Helper.lastCalled); // [heure de dernier appel de someTask()]
}
}
}
Flash CS3
M'envoyer un message électronique lorsque des commentaires sont ajoutés à cette page | Rapport de commentaire
Page en cours: http://livedocs.adobe.com/flash/9.0_fr/main/00000042.html