Pakete und Namespaces

Pakete und Namespaces sind miteinander verwandte Konzepte. Mit Paketen können Sie Klassendefinitionen bündeln, um die gemeinsame Nutzung von Code zu vereinfachen und Benennungskonflikte zu minimieren. Mit Namespaces steuern Sie die Sichtbarkeit von Bezeichnern, wie z. B. Eigenschaften- und Methodennamen. Namespaces können auf Code unabhängig davon angewendet werden, ob dieser sich innerhalb oder außerhalb eines Pakets befindet. Pakete ermöglichen Ihnen das Strukturieren Ihrer Klassendateien, mit Namespaces verwalten Sie die Sichtbarkeit von einzelnen Eigenschaften und Methoden.

Pakete

In ActionScript 3.0 werden Pakete mit Namespaces implementiert, dennoch sind Pakete und Namespaces keine Synonyme. Beim Deklarieren eines Paketes erstellen Sie implizit einen Sondertyp eines Namespace, der dann bei der Kompilierung garantiert bekannt ist. Explizit erstelle Namespaces hingegen sind bei der Kompilierung nicht unbedingt bekannt.

Im folgenden Beispiel wird die Direktive package zum Erstellen eines einfachen Pakets verwendet, das eine Klasse enthält:

package samples 
{ 
    public class SampleCode 
    { 
        public var sampleGreeting:String; 
        public function sampleFunction() 
        { 
            trace(sampleGreeting + " from sampleFunction()"); 
        } 
    } 
}

Der Name der Klasse in diesem Beispiel lautet „SampleCode“. Da sich die Klasse im samples-Paket befindet, wandelt der Compiler den Klassennamen während der Kompilierung automatisch in dessen vollständig qualifizierten Namen (samples.SampleCode) um. Darüber hinaus wandelt der Compiler die Namen aller Eigenschaften oder Methoden um, sodass sampleGreeting und sampleFunction() zu samples.SampleCode.sampleGreeting und samples.SampleCode.sampleFunction() werden.

Viele Entwickler, insbesondere diejenigen mit Erfahrungen in der Programmierung mit Java, platzieren Klassen nur in der obersten Ebene eines Pakets. ActionScript 3.0 unterstützt in der obersten Ebene eines Pakets jedoch nicht nur Klassen, sondern auch Variablen, Funktionen und sogar Anweisungen. Eine erweiterte Einsatzmöglichkeit dieses Merkmals ist das Definieren eines Namespace auf der obersten Ebene eines Pakets, sodass er allen Klassen in diesem Paket zur Verfügung steht. Denken Sie jedoch daran, dass nur zwei Zugriffsbezeichner, public und internal, auf der obersten Ebene eines Pakets zulässig sind. Im Gegensatz zur Programmiersprache Java, bei der Sie verschachtelte Klassen als private Klassen deklarieren können, unterstützt ActionScript 3.0 weder verschachtelte noch private Klassen.

In vielerlei Hinsicht ähneln ActionScript 3.0-Pakete den Paketen in der Programmiersprache Java. Wie Sie im vorangegangenen Beispiel gesehen haben, werden vollständig qualifizierte Paketverweise ebenso wie in Java mit dem Punktoperator (.) ausgedrückt. Mit Paketen können Sie Ihren Code intuitiv und hierarchisch anordnen, sodass er auch von anderen Programmierern verwendet werden kann. Dies vereinfacht die gemeinsame Nutzung von Code, indem von Ihnen erstellte Pakete von anderen Programmierern verwendet und Sie von anderen Programmierern erstellte Pakete in Ihren Code integrieren können.

Darüber hinaus können Sie mit Paketen sicherstellen, dass von Ihnen verwendete Bezeichnernamen einmalig sind und somit nicht zu Konflikten mit anderen Bezeichnernamen führen. Viele sagen sogar, dass dies der wichtigste Vorteil von Paketen ist. Angenommen, zwei Programmierer möchten ihren Code gemeinsam verwenden. Jeder hat eine Klasse mit der Bezeichnung „SampleCode“ erstellt. Ohne Pakete würde dies zu einem Namenskonflikt führen. Die einzige Lösung wäre, eine der beiden Klassen umzubenennen. Mit Paketen lässt sich der Namenskonflikt einfach vermeiden, indem eine Klasse (oder am besten beide Klassen) in Paketen mit einmaligen Namen platziert werden.

Sie können auch eingebettete Punkte in Ihren Paketnamen aufnehmen, um verschachtelte Pakete zu erstellen. Auf diese Weise können Sie eine hierarchische Paketstruktur anlegen. Ein gutes Beispiel hierfür ist das von ActionScript 3.0 bereitgestellte flash.display-Paket, das im flash-Paket verschachtelt ist.

Der Großteil von ActionScript 3.0 ist unter dem flash-Paket organisiert. Beispielsweise enthält das flash.display-Paket die API für die Anzeigeliste und das flash.events-Paket das neue Ereignismodell.

Erstellen von Paketen

ActionScript 3.0 bietet Ihnen eine enorme Flexibilität bei der Strukturierung Ihrer Pakete, Klassen und Quelldateien. Frühere ActionScript-Versionen gestatteten nur eine Klasse pro Quelldatei und verlangten, dass der Name der Quelldatei dem Namen der Klasse entsprach. Mit ActionScript 3.0 können Sie mehrere Klassen in eine Quelldatei aufnehmen, doch für Code außerhalb der Datei ist pro Datei nur eine Klasse verfügbar. Anders ausgedrückt, in einer Paketdeklaration kann in jeder Datei nur eine Klasse deklariert werden. Sie müssen alle zusätzlichen Klassen außerhalb Ihrer Paketdefinition deklarieren. Auf diese Weise werden diese Klassen auch für Code sichtbar, der sich außerhalb dieser Quelldatei befindet. Der Name der innerhalb einer Paketdefinition deklarierten Klasse muss dem Namen der Quelldatei entsprechen.

Darüber hinaus bietet ActionScript 3.0 mehr Flexibilität bei der Deklaration von Paketen. In früheren Versionen von ActionScript waren Pakete lediglich Verzeichnisse, in denen Sie Quelldateien platzierten. Sie haben keine Pakete mit der package-Anweisung deklariert, sondern stattdessen den Paketnamen als Teil des vollständig qualifizierten Klassennamens in Ihre Klassendeklaration aufgenommen. Obwohl Pakete in ActionScript 3.0 noch immer Verzeichnisse darstellen, können sie mehr als nur Klassen enthalten. In ActionScript 3.0 deklarieren Sie ein Paket mit der Anweisung package, d. h. Sie können auch Variable, Funktionen und Namespaces auf oberster Ebene eines Pakets deklarieren. Es ist sogar möglich, ausführbare Anweisungen in die oberste Ebene eines Pakets aufzunehmen. Wenn Sie Variablen, Funktionen oder Namespaces auf der obersten Ebene eines Pakets deklarieren, stehen Ihnen nur die Attribute public und internal zur Verfügung. Darüber hinaus kann nur eine Deklaration auf Paketebene pro Datei das Attribut public verwenden, unabhängig davon, ob eine Klasse, Variable, Funktion oder ein Namespace deklariert wird.

Pakete eignen sich insbesondere zum Strukturieren Ihres Codes und zum Vermeiden von Namenskonflikten. Verwechseln Sie das Konzept der Pakete jedoch nicht mit dem Konzept der Klassenvererbung. Zwei Klassen im selben Paket haben den gleichen Namespace, müssen aber nicht unbedingt miteinander verwandt sein. Entsprechend hat ein verschachteltes Paket möglicherweise keine semantische Beziehung zu seinem übergeordneten Paket.

Importieren von Paketen

Wenn Sie eine Klasse in einem Paket verwenden möchten, müssen Sie entweder das Paket oder die gewünschte Klasse importieren. Diese Vorgehensweise unterscheidet sich von der in ActionScript 2.0; hier war das Importieren von Klassen optional.

Dies kann anhand des bereits genannten Beispiels der SampleCode-Klasse verdeutlicht werden. Wenn sich die Klasse in einem Paket namens „samples“ befindet, müssen Sie die Klasse mit einer der folgenden Anweisungen importieren, bevor Sie sie verwenden können:

import samples.*;

oder

import samples.SampleCode;

Im Allgemeinen müssen import-Anweisungen so genau wie möglich angegeben werden. Wenn Sie nur die SampleCode-Klasse aus dem samples-Paket verwenden möchten, so importieren Sie anstelle des gesamten Pakets nur die SampleCode-Klasse. Das Importieren gesamter Pakete kann zu unerwarteten Namenskonflikten führen.

Der Quellcode, der das Paket oder die Klasse definiert, muss in Ihrem Klassenpfad platziert werden. Der Klassenpfad ist eine benutzerdefinierte Liste der lokalen Verzeichnispfade, die festlegt, wo der Compiler nach importierten Paketen und Klassen sucht. Manchmal wird der Klassenpfad auch als Erstellungspfad oder Quellpfad bezeichnet.

Nachdem die Klasse oder das Paket korrekt importiert wurde, können Sie entweder den vollständig qualifizierten Namen der Klasse (samples.SampleCode) oder einfach nur den Klassennamen selbst (SampleCode) verwenden.

Vollständig qualifizierte Namen eignen sich insbesondere dann, wenn identisch benannte Klassen, Methoden oder Eigenschaften zu mehrdeutigem Code führen, sind aber schwierig zu verwalten, wenn sie für alle Bezeichner verwendet werden. Wenn Sie z. B. eine SampleCode-Klasseninstanz instanziieren, wird der Code durch die Verwendung von vollständig qualifizierten Namen sehr lang:

var mySample:samples.SampleCode = new samples.SampleCode();

Je größer die Anzahl der Ebenen in den verschachtelten Paketen ist, desto schlechter ist die Lesbarkeit des Codes. Wenn Sie sicher sind, dass mehrdeutige Bezeichner kein Problem darstellen, können Sie die Lesbarkeit Ihres Codes verbessern, indem Sie einfache Bezeichner verwenden. Beispielsweise wird das Instanziieren einer neuen Instanz der SampleCode-Klasse weit weniger ausführlich, wenn Sie nur den Klassenbezeichner verwenden:

var mySample:SampleCode = new SampleCode();

Wenn Sie hingegen versuchen, die Bezeichnernamen zu verwenden, ohne zunächst das entsprechende Paket bzw. die entsprechende Klasse zu importieren, kann der Compiler die Klassendefinitionen nicht finden. Wenn Sie andererseits ein Paket oder eine Klasse importieren, führt jeder Versuch, einen Namen zu definieren, der mit einem importierten Namen in Konflikt steht, zu einer Fehlermeldung.

Nach dem Erstellen eines Pakets lautet der standardmäßige Zugriffsbezeichner für alle Mitglieder dieses Pakets internal. Dies wiederum bedeutet, dass alle Paketmitglieder standardmäßig nur für andere Mitglieder des Pakets sichtbar sind. Soll eine Klasse auch für Code außerhalb des Pakets zugänglich sein, müssen Sie die Klasse als public (öffentlich) deklarieren. Das folgende Paket enthält beispielsweise zwei Klassen, SampleCode und CodeFormatter:

// SampleCode.as file 
package samples 
{ 
    public class SampleCode {} 
} 
 
// CodeFormatter.as file 
package samples 
{ 
    class CodeFormatter {} 
}

Die SampleCode-Klasse ist auch außerhalb des Pakets sichtbar, da sie als public deklariert wurde. Die CodeFormatter-Klasse ist jedoch nur innerhalb des samples-Pakets selbst sichtbar. Wenn Sie versuchen, außerhalb des samples-Pakets auf die CodeFormatter-Klasse zuzugreifen, wird eine Fehlermeldung erzeugt. Dies wird im folgenden Beispiel gezeigt:

import samples.SampleCode; 
import samples.CodeFormatter; 
var mySample:SampleCode = new SampleCode(); // okay, public class 
var myFormatter:CodeFormatter = new CodeFormatter(); // error

Sollen beide Klassen auch für Code außerhalb des Pakets zugänglich sein, müssen Sie beide Klassen als public deklarieren. Sie können das Attribut public jedoch nicht auf die Paketdeklaration anwenden.

Vollständig qualifizierte Namen eignen sich zum Auflösen von Namenskonflikten, die bei der Verwendung von Paketen auftreten können. Ein solcher Fall kann entstehen, wenn Sie zwei Pakete importieren, in denen Klassen mit dem gleichen Bezeichner definiert sind. Das folgende Paket enthält beispielsweise eine Klasse mit der Bezeichnung „SampleCode“:

package langref.samples 
{ 
    public class SampleCode {} 
}

Wenn Sie beide Klassen importieren, entsteht bei Verwendung der SampleCode-Klasse ein Namenskonflikt. Dies wird im folgenden Beispiel gezeigt:

import samples.SampleCode; 
import langref.samples.SampleCode; 
var mySample:SampleCode = new SampleCode(); // name conflict

Der Compiler weiß nicht, welche SampleCode-Klasse verwendet werden soll. Um diesen Konflikt aufzulösen, müssen Sie den vollständig qualifizierten Namen jeder Klasse angeben:

var sample1:samples.SampleCode = new samples.SampleCode(); 
var sample2:langref.samples.SampleCode = new langref.samples.SampleCode();
Hinweis: Programmierer mit Erfahrungen in C++ verwechseln häufig die import-Anweisung mit #include. Die #include-Direktive ist in C++ unbedingt erforderlich, da C++-Compiler nur jeweils eine Datei verarbeiten und nicht in anderen Dateien nach Klassendefinitionen suchen, es sei denn, es ist explizit eine Headerdatei enthalten. ActionScript 3.0 enthält eine include-Direktive, aber sie ist nicht zum Importieren von Klassen und Paketen vorgesehen. Zum Importieren von Klassen und Paketen in ActionScript 3.0 verwenden Sie die import-Anweisung und legen die Quelldatei mit dem Paket im Klassenpfad ab.

Namespaces

Mit Namespaces haben Sie die Kontrolle über die Sichtbarkeit der von Ihnen erstellten Eigenschaften und Methoden. Stellen Sie sich die Zugriffskontrollbezeichner public, private, protected und internal als integrierte Namespaces vor. Wenn diese vordefinierten Zugriffskontrollbezeichner für Ihre Zwecke nicht ausreichen, können Sie eigene Namespaces erstellen.

Wenn Sie mit XML-Namespaces Erfahrung haben, wird Ihnen vieles vertraut vorkommen, obwohl Syntax und Details der ActionScript-Implementierung leicht von denen für XML abweichen. Auch wenn Sie noch nie mit Namespaces gearbeitet haben, können Sie unbesorgt sein – das Konzept ist einfach, doch die Implementierung verwendet einige spezielle Begriffe, die Sie lernen müssen.

Um das Konzept der Namespaces zu verstehen, müssen Sie zunächst einmal wissen, das der Name einer Eigenschaft oder Methode immer zwei Teile enthält: einen Bezeichner und einen Namespace. Der Bezeichner ist das, was Sie sich im Allgemeinen unter dem Namen vorstellen. Beispielsweise lauten die Bezeichner in der folgenden Klassendefinition sampleGreeting und sampleFunction():

class SampleCode 
{ 
    var sampleGreeting:String; 
    function sampleFunction () { 
        trace(sampleGreeting + " from sampleFunction()"); 
    } 
}

Wenn Definitionen kein Namespace-Attribut vorangestellt ist, sind die entsprechenden Namen immer durch den Standardnamespace internal qualifiziert. Das bedeutet, sie sind nur für aufrufende Objekte im gleichen Paket sichtbar. Ist der Compiler auf den strikten Modus gesetzt, gibt er eine Warnung aus, dass der Namespace internal für alle Bezeichner ohne Namespace-Attribut gilt. Um sicherzustellen, dass ein Bezeichner überall zur Verfügung steht, müssen Sie dem Bezeichnernamen explizit das Attribut public voranstellen. Im vorangegangenen Beispielcode haben sowohl sampleGreeting als auch sampleFunction() den Namespace-Wert internal.

Bei der Verwendung von Namespaces sind drei grundlegende Schritte zu beachten: Zunächst definieren Sie den Namespace mit dem Schlüsselwort namespace. Beispielsweise definiert der folgende Code den Namespace version1:

namespace version1;

Dann wenden Sie den Namespace an, indem Sie ihn anstelle eines Zugriffskontrollbezeichners in einer Eigenschafts- oder Methodendeklaration verwenden. Das folgende Beispiel fügt eine Funktion namens myFunction() im Namespace version1 ein:

version1 function myFunction() {}

Nachdem Sie den Namespace angewendet haben, können Sie im dritten Schritt mit der Direktive use oder durch Qualifizieren des Bezeichnernamens mit einem Namespace auf den angewendeten Namespace verweisen. Das folgende Beispiel verweist über die use-Direktive auf die myFunction()-Funktion:

use namespace version1; 
myFunction();

Sie können auch einen qualifizierten Namen verwenden, um auf die myFunction()-Funktion zu verweisen. Dies ist im folgenden Beispiel dargestellt:

version1::myFunction();

Definieren von Namespaces

Namespaces enthalten einen Wert, den Uniform Resource Identifier (URI), der manchmal auch als Namespace-Name bezeichnet wird. Mit einem URI können Sie sicherstellen, dass Ihre Namespace-Definition einmalig ist.

Ein Namespace wird durch das Deklarieren einer Namespace-Definition erstellt. Dabei stehen Ihnen zwei Verfahren zur Verfügung: Entweder definieren Sie einen Namespace mit einem expliziten URI, als ob Sie einen XML-Namespace definieren würden, oder Sie lassen den URI weg. Das folgende Beispiel zeigt, wie ein Namespace mit einem URI definiert wird:

namespace flash_proxy = "http://www.adobe.com/flash/proxy";

Der URI dient als eindeutiger Identifikationsstring für diesen Namespace. Wenn Sie den URI weglassen, erstellt der Compiler einen eindeutigen internen Identifikationsstring anstelle des URI, wie im folgenden Beispiel dargestellt. Sie können nicht auf diesen internen Identifikationsstring zugreifen.

namespace flash_proxy;

Nach der Definition eines Namespace – ob mit oder ohne URI – kann dieser Namespace im gleichen Gültigkeitsbereich nicht mehr neu definiert werden. Der Versuch, einen Namespace zu definieren, obwohl schon ein Namespace im gleichen Gültigkeitsbereich existiert, führt zu einem Compiler-Fehler.

Ein in einem Paket oder einer Klasse definierter Namespace ist für Code außerhalb des Pakets oder der Klasse nicht sichtbar, es sei denn, es wird der entsprechende Zugriffskontrollbezeichner verwendet. Beispielsweise wurde der Namespace flash_proxy im folgenden Code im flash.utils-Paket definiert. Im folgenden Code bedeutet das Fehlen eines Zugriffskontrollbezeichners, dass der Namespace flash_proxy nur für Code innerhalb des flash.utils-Paket und nicht für Code außerhalb des Pakets sichtbar ist:

package flash.utils 
{ 
    namespace flash_proxy; 
}

Im folgenden Code wird das public-Attribut verwendet, um den flash_proxy-Namespace auch für Code außerhalb des Pakets sichtbar zu machen:

package flash.utils 
{ 
    public namespace flash_proxy; 
}

Anwenden von Namespaces

Unter Anwenden eines Namespace ist das Platzieren einer Definition in einem Namespace zu verstehen. In Namespaces können Funktionen, Variablen und Konstanten platziert werden (das Platzieren einer Klasse in einem benutzerdefinierten Namespace ist nicht möglich).

Betrachten Sie das Beispiel einer Funktion, die mit dem Zugriffskontroll-Namespace public deklariert wurde. Mit dem public-Attribut in einer Funktionsdefinition wird die Funktion in einem öffentlichen (public) Namespace platziert, wodurch die Funktion für jeden Code verfügbar ist. Ein definierter Namespace kann auf die gleiche Weise wie das public-Attribut verwendet werden, und die Definition ist für Code verfügbar, der auf Ihren benutzerdefinierten Namespace verweisen kann. Angenommen Sie haben einen Namespace example1 definiert, so können Sie eine Methode mit der Bezeichnung myFunction() mit dem Attribut example1 hinzufügen. Dies wird im folgenden Beispiel gezeigt:

namespace example1; 
class someClass 
{ 
    example1 myFunction() {} 
}

Das Deklarieren der myFunction()-Methode mit dem Namespace example1 als Attribut bedeutet, dass die Methode zum Namespace example1 gehört.

Beim Anwenden von Namespaces müssen Sie Folgendes berücksichtigen:

  • Sie können in jeder Deklaration nur einen Namespace anwenden.

  • Es gibt keine Möglichkeit, ein Namespace-Attribut auf mehrere Definitionen gleichzeitig anzuwenden. Mit anderen Worten, wenn Sie Ihren Namespace auf zehn verschiedene Funktionen anwenden möchten, müssen Sie Ihren Namespace jeder dieser zehn Funktionsdefinitionen hinzufügen.

  • Beim Anwenden eines Namespace können Sie keinen Zugriffskontrollbezeichner angeben, da sich Namespaces und Zugriffskontrollbezeichner gegenseitig ausschließen. Sie können also eine Funktion oder Eigenschaft zusätzlich zum Anwenden Ihres Namespace nicht als public, private, protected oder internal deklarieren.

Referenzieren von Namespaces

Wenn Sie eine Methode oder Eigenschaft verwenden, die mit einem der Zugriffskontroll-Namespaces wie public, private, protected und internal deklariert wurde, ist kein expliziter Verweis auf einen Namespace mehr erforderlich. Dies liegt daran, dass der Zugriff auf diese speziellen Namespaces über den Kontext gesteuert wird. Im Namespace private platzierte Definitionen stehen beispielsweise automatisch für Code in der gleichen Klasse zur Verfügung. Für benutzerdefinierte Namespaces existiert eine solche Kontextempfindlichkeit jedoch nicht. Um eine von Ihnen in einem benutzerdefinierten Namespace platzierte Methode oder Eigenschaft zu verwenden, müssen Sie den Namespace referenzieren.

Verweise auf Namespaces erstellen Sie mit der Direktive use namespace, oder Sie qualifizieren den Namen mit dem Namensqualifizierter (::). Das Referenzieren eines Namespace mit der Direktive use namespace „öffnet“ den Namespace, sodass er auf alle nicht qualifizierten Bezeichner angewendet werden kann. Angenommen Sie haben den Namespace example1 definiert, so können Sie mithilfe von use namespace example1 auf Namen in diesem Namespace zugreifen:

use namespace example1; 
myFunction();

Sie können mehrere Namespaces gleichzeitig öffnen. Nachdem Sie einen Namespace mit use namespace geöffnet haben, bleibt er über den gesamten Codeblock, in dem er geöffnet wurde, offen. Es gibt keine Möglichkeit, einen Namespace explizit zu schließen.

Wenn mehrere Namespaces geöffnet sind, erhöht sich jedoch die Wahrscheinlichkeit von Namenskonflikten. Wenn Sie einen Namespace nicht öffnen möchten, können Sie die Direktive use namespace vermeiden, indem Sie den Methoden- oder Eigenschaftennamen mit dem Namespace und dem Namensqualifizierer qualifizieren. Das folgende Beispiel zeigt, wie der Name myFunction() mit dem Namespace example1 qualifiziert wird:

example1::myFunction();

Verwenden von Namespaces

In der flash.utils.Proxy-Klasse, die einen Teil von ActionScript 3.0 bildet, finden Sie ein realistisches Beispiel eines Namespace, durch dessen Verwendung Namenskonflikte verhindert werden. Die Proxy-Klasse, ein Ersatz für die Object.__resolve-Eigenschaft aus ActionScript 2.0, ermöglicht Ihnen das Abfangen von Verweisen auf nicht definierte Eigenschaften oder Methoden, bevor ein Fehler auftritt. Alle Methoden der Proxy-Klasse befinden sich im flash_proxy-Namespace, um Namenskonflikte zu verhindern.

Um die Einsatzmöglichkeiten des flash_proxy-Namespace besser zu verstehen, müssen Sie wissen, wie die Proxy-Klasse verwendet wird. Die Funktionsmerkmale der Proxy-Klasse stehen nur den Klassen zur Verfügung, die von der Proxy-Klasse erben. Anders ausgedrückt, wenn Sie die Methoden der Proxy-Klasse an einem Objekt anwenden möchten, muss die Klassendefinition des Objekts auf die Proxy-Klasse ausgeweitet werden. Wenn Sie beispielsweise Versuche zum Aufrufen einer nicht definierten Methode abfangen möchten, so müssen Sie die Proxy-Klasse ausweiten und dann die callProperty()-Methode der Proxy-Klasse außer Kraft setzen.

Sie werden sich erinnern, dass das Implementieren von Namespaces im Allgemeinen ein dreistufiger Prozess ist, der sich aus dem Definieren, Anwenden und Referenzieren eines Namespace zusammensetzt. Da Sie jedoch keine der Methoden der Proxy-Klasse explizit aufrufen, wird der flash_proxy-Namespace nur definiert und angewendet, aber nicht referenziert. ActionScript 3.0 definiert den flash_proxy-Namespace und wendet ihn in der Proxy-Klasse an. Ihr Code muss den flash_proxy-Namespace nur auf die Klassen anwenden, welche die Proxy-Klasse erweitern.

Der flash_proxy-Namespace ist etwa wie folgt in dem flash.utils-Paket definiert:

package flash.utils 
{ 
    public namespace flash_proxy; 
}

Der Namespace wird auf die Methoden der Proxy-Klasse angewendet, wie im folgenden Codeausschnitt der Proxy-Klasse dargestellt ist:

public class Proxy 
{ 
    flash_proxy function callProperty(name:*, ... rest):* 
    flash_proxy function deleteProperty(name:*):Boolean 
    ... 
}

Wie der folgende Code veranschaulicht, müssen Sie zunächst sowohl die Proxy-Klasse als auch den flash_proxy-Namespace importieren. Dann deklarieren Sie Ihre Klasse so, dass sie die Proxy-Klasse erweitert (außerdem müssen Sie das Attribut dynamic hinzufügen, wenn Sie im strikten Modus kompilieren). Falls Sie die callProperty()-Methode außer Kraft setzen, müssen Sie den flash_proxy-Namespace verwenden.

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); 
        } 
    } 
}

Wenn Sie eine Instanz der MyProxy-Klasse erstellen und eine nicht definierte Methode, wie z. B. die testing()-Methode, aufrufen (siehe folgendes Beispiel), fängt das Proxy-Objekt den Methodenaufruf ab und führt die Anweisungen in der überschriebenen callProperty()-Methode aus (in diesem Fall eine einfache trace()-Anweisung).

var mySample:MyProxy = new MyProxy(); 
mySample.testing(); // method call intercepted: testing

Die Aufnahme der Methoden der Proxy-Klasse in den flash_proxy-Namespace hat zwei Vorteile. Zunächst wird durch einen separaten Namespace die öffentliche Schnittstelle jeder Klasse übersichtlicher, welche die Proxy-Klasse erweitert. (Es gibt etwa ein Dutzend Methoden in der Proxy-Klasse, die Sie außer Kraft setzen können. Keine dieser Methoden wird direkt aufgerufen. Das Platzieren aller dieser Methoden im öffentlichen Namespace könnte verwirrend wirken.) Darüber hinaus werden durch Verwenden des flash_proxy-Namespace Namenskonflikte vermieden, falls Ihre Proxy-Unterklasse Instanzenmethoden mit Namen enthält, die Methoden in der Proxy-Klasse gleichen. Angenommen Sie möchten eine Ihrer eigenen Methoden callProperty() nennen. Der folgende Code wird akzeptiert, da sich Ihre Version der callProperty()-Methode in einem anderen Namespace befindet:

dynamic class MyProxy extends Proxy 
{ 
    public function callProperty() {} 
    flash_proxy override function callProperty(name:*, ...rest):* 
    { 
        trace("method call intercepted: " + name); 
    } 
}

Mit Namespaces kann auch ein Zugriff auf Methoden oder Eigenschaften bereitgestellt werden, der nicht über die vier Zugriffskontrollbezeichner (public, private, internal und protected) möglich ist. Vielleicht haben Sie einige Dienstprogrammmethoden, die über mehrere Pakete verteilt sind. Diese Methoden sollen für alle Pakete zur Verfügung stehen, Sie möchten sie aber nicht als öffentliche Methoden deklarieren. In diesem Fall erstellen Sie einen Namespace und verwenden ihn als Ihren eigenen speziellen Zugriffskontrollbezeichner.

Im folgenden Beispiel werden zwei Funktionen aus unterschiedlichen Paketen in einem benutzerdefinierten Namespace zusammengeführt. Durch Gruppieren dieser Funktionen im gleichen Namespace können Sie beide Funktionen mit nur einer use namespace-Anweisung für eine Klasse oder ein Paket sichtbar machen.

Dieses Beispiel verwendet vier Dateien, um diese Technik zu veranschaulichen. Alle Dateien müssen sich in Ihrem Klassenpfad befinden. Die erste Datei, „myInternal.as“, dient zum Definieren des myInternal-Namespace. Da sich diese Datei in einem Paket namens „example“ befindet, müssen Sie die Datei in einem Ordner mit der Bezeichnung „example“ speichern. Der Namespace wird als public markiert, sodass er in andere Pakete importiert werden kann.

// myInternal.as in folder example 
package example 
{ 
    public namespace myInternal = "http://www.adobe.com/2006/actionscript/examples"; 
}

Mit der zweiten Datei, „Utility.as“, und der dritten Datei, „Helper.as“, werden die Klassen mit den Methoden definiert, die anderen Paketen zur Verfügung stehen sollen. Die Utility-Klasse befindet sich im Paket „example.alpha“. Dies bedeutet, dass die Datei in einem Ordner namens „alpha“ gespeichert werden muss, der wiederum ein Unterordner von „example“ ist. Die Helper-Klasse befindet sich im Paket „example.beta“. Dies bedeutet, dass die Datei in einem Ordner namens „beta“ gespeichert werden muss, der wiederum ein Unterordner von „example“ ist. Beide Pakete, „example.alpha“ und „example.beta“, müssen den Namespace importieren, bevor sie ihn verwenden können.

// Utility.as in the example/alpha folder 
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 in the example/beta folder 
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; 
        } 
    } 
}

Die vierte Datei, „NamespaceUseCase.as“, ist die Hauptanwendungsklasse. Sie muss sich in einem Ordner auf gleicher Ebene wie „example“ befinden. In Flash Professional würde diese Klasse als Dokumentklasse für die FLA-Datei verwendet werden. Die NamespaceUseCase-Klasse importiert auch den myInternal-Namespace und verwendet ihn zum Aufrufen der beiden statischen Methoden, die sich in den anderen Paketen befinden. In diesem Beispiel werden statische Methoden nur zur Vereinfachung des Codes verwendet. Im Namespace myInternal können sowohl statische als auch Instanzmethoden platziert werden.

// NamespaceUseCase.as 
package 
{ 
    import flash.display.MovieClip; 
    import example.myInternal; // import namespace 
    import example.alpha.Utility;// import Utility class 
    import example.beta.Helper;// import Helper class 
     
    public class NamespaceUseCase extends MovieClip 
    { 
        public function NamespaceUseCase() 
        { 
            use namespace myInternal; 
             
            Utility.someTask(); 
            Utility.someTask(); 
            trace(Utility.taskCounter); // 2 
             
            Helper.someTask(); 
            trace(Helper.lastCalled); // [time someTask() was last called] 
        } 
    } 
}