Klassen

Eine Klasse ist eine abstrakte Darstellung eines Objekts. Eine Klasse speichert Informationen über die Datentypen, die ein Objekt aufnehmen kann, und die Verhalten, die ein Objekt an den Tag legen kann. Der Nutzen einer solchen Abstraktion wird nicht sofort offensichtlich, wenn Sie kleine Skripts schreiben, die nur wenige miteinander interagierende Objekte enthalten. Doch je größer ein Programm, desto mehr Objekte müssen verwaltet werden. In diesem Fall können Sie mithilfe von Klassen die Erstellungsweise und Interaktion von Objekten besser steuern.

Bereits in ActionScript 1.0 konnten ActionScript-Programmierer function-Objekte verwenden, um Konstrukte zu erstellen, die den heutigen Klassen ähnelten. Mit ActionScript 2.0 ist eine formale Unterstützung für Klassen mit Schlüsselwörtern wie class und extends hinzugekommen. ActionScript 3.0 unterstützt die in ActionScript 2.0 eingeführten Schlüsselwörter, bietet jedoch zudem neue Möglichkeiten. So ermöglicht ActionScript 3.0 beispielsweise eine verbesserte Zugriffskontrolle über die Attribute protected und internal. Weiterhin verbessern die Schlüsselwörter final und override die Vererbungssteuerung.

Entwickler, die in Programmiersprachen wie Java, C++ oder C# Klassen erstellt haben, werden sich in ActionScript leicht zurechtfinden. ActionScript verwendet zahlreiche derselben Schlüsselwörter und Attributnamen, wie class, extends und public.

Hinweis: In der Dokumentation zu Adobe ActionScript bezieht sich der Begriff „Eigenschaft“ auf ein beliebiges Mitglied eines Objekts oder einer Klasse, einschließlich Variablen, Konstanten und Methoden. Darüber hinaus haben hier die Begriffe „Klasse“ und „statisch“ unterschiedliche Bedeutungen, obwohl sie häufig als Synonyme verwendet werden. Beispielsweise bezieht sich der Begriff „Klasseneigenschaften“ auf alle Mitglieder einer Klasse und nicht nur auf statische Mitglieder.

Klassendefinitionen

Für Klassendefinitionen in ActionScript 3.0 wird eine ähnliche Syntax wie für Klassendefinitionen in ActionScript 2.0 verwendet. Die richtige Syntax einer Klassendefinition umfasst zunächst das Schlüsselwort class, gefolgt vom Klassennamen. Dem Klassennamen folgt der in geschweifte Klammern ({}) eingeschlossene Klassenrumpf. Im folgenden Beispielcode wird eine neue Klasse namens „Shape“ erstellt, die eine Variable namens visible enthält:

public class Shape 
{ 
    var visible:Boolean = true; 
}

Eine wichtige Syntaxänderung betrifft Klassendefinitionen, die sich in einem Paket befinden. In ActionScript 2.0 galt: Wenn sich eine Klasse in einem Paket befindet, muss der Paketname in der Klassendeklaration enthalten sein. n ActionScript 3.0, mit dem die package-Anweisung eingeführt wird, muss sich der Paketname nicht mehr in der Klassen-, sondern in der Paketdeklaration befinden. Die folgenden Klassendeklarationen zeigen, wie die BitmapData-Klasse, die Teil des flash.display-Pakets ist, in ActionScript 2.0 und ActionScript 3.0 definiert wird:

// ActionScript 2.0 
class flash.display.BitmapData {} 
 
// ActionScript 3.0 
package flash.display 
{ 
    public class BitmapData {} 
}

Klassenattribute

Mit ActionScript 3.0 können Sie Klassendefinitionen mit einem der folgenden vier Attribute bearbeiten:

Attribut

Definition

dynamic

Ermöglicht zur Laufzeit das Hinzufügen von Eigenschaften zu Instanzen.

final

Kann nicht von einer anderen Klasse erweitert werden.

internal (Standard)

Sichtbar für Verweise innerhalb des aktuellen Pakets.

public

Sichtbar für alle Verweise.

Bei jedem dieser Attribute (außer bei internal) wird das Attribut explizit eingeschlossen, um das zugewiesene Verhalten zu erhalten. Wenn Sie beispielsweise beim Definieren einer Klasse das dynamic-Attribut weglassen, können Sie einer Klasseninstanz zur Laufzeit keine Eigenschaften hinzufügen. Ein Attribut wird explizit zugewiesen, indem Sie es am Anfang der Klassendefinition platzieren. Dies wird im folgenden Code gezeigt:

dynamic class Shape {}

Beachten Sie, dass die Liste kein Attribut namens abstract enthält, Abstrakte Klassen werden in ActionScript 3.0 nicht unterstützt. Beachten Sie außerdem, dass die Liste keine Attribute namens private und protected enthält. Diese Attribute sind nur innerhalb einer Klassendefinition von Bedeutung und können nicht auf Klassen selbst angewendet werden. Soll eine Klasse auch außerhalb eines Pakets öffentlich sichtbar sein, platzieren Sie die Klasse in einem Paket und weisen ihr dann das Attribut internal zu. Alternativ können Sie die beiden Attribute internal und public weglassen. In diesem Fall fügt der Compiler das Attribut internal automatisch hinzu. Sie können eine Klasse auch so definieren, dass sie nur in der Quelldatei sichtbar ist, in der sie definiert wurde. Platzieren Sie die Klasse unten in der Quelldatei, unter der schließenden geschweiften Klammer der Paketdefinition.

Klassenrumpf

Der Rumpf der Klasse ist in geschweifte Klammern eingeschlossen. Er definiert die Variablen, Konstanten und Methoden der Klasse. Das folgende Beispiel zeigt die Deklaration für die Accessibility-Klasse in ActionScript 3.0:

public final class Accessibility 
{ 
    public static function get active():Boolean; 
    public static function updateProperties():void; 
}

Sie können auch einen Namespace in einem Klassenrumpf definieren. Im folgenden Beispielcode wird gezeigt, wie ein Namespace in einem Klassenrumpf definiert und als Attribut für eine Methode in dieser Klasse verwendet werden kann:

public class SampleClass 
{ 
    public namespace sampleNamespace; 
    sampleNamespace function doSomething():void; 
}

Mit ActionScript 3.0 können Sie nicht nur Definitionen, sondern auch Anweisungen in einen Klassenrumpf aufnehmen. Anweisungen, die sich innerhalb des Klassenrumpfes, aber außerhalb einer Methodendefinition befinden, werden genau einmal ausgeführt. Diese Ausführung tritt auf, wenn die Klassendefinition zum ersten Mal erkannt wird und das zugehörige Klassenobjekt erstellt wird. Der folgende Beispielcode enthält einen Aufruf der externen Funktion hello() und eine trace-Anweisung, die eine Bestätigungsmeldung ausgibt, wenn die Klasse definiert ist:

function hello():String 
{ 
    trace("hola"); 
} 
class SampleClass 
{ 
    hello(); 
    trace("class created"); 
} 
// output when class is created 
hola 
class created

In ActionScript 3.0 ist es zulässig, eine statische Eigenschaft und eine Instanzeigenschaft mit dem gleichen Namen im gleichen Klassenrumpf zu definieren. Im folgenden Beispielcode werden eine statische Variable namens message und eine Instanzvariable mit dem gleichen Namen deklariert:

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

Klassen-Eigenschaftenattribute

In Abhandlungen über das ActionScript-Objektmodell wird der Begriff Eigenschaft für alles verwendet, was ein Mitglied einer Klasse sein kann; dazu gehören auch Variable, Konstanten und Methoden. Im Referenzhandbuch zu Adobe ActionScript 3.0 für die Adobe Flash-Plattform wird der Begriff jedoch im engeren Sinne verwendet. In diesem Zusammenhang bezieht sich der Begriff „Eigenschaft“ nur auf Klassenmitglieder, die Variablen sind oder die von einer Get- oder Set-Methode definiert werden. In ActionScript 3.0 gibt es eine Reihe von Attributen, die mit jeder Eigenschaft einer Klasse verwendet werden können. Diese Attribute sind in der folgenden Tabelle aufgeführt.

Attribut

Definition

internal (Standard)

Sichtbar für Verweise innerhalb des gleichen Pakets.

private

Sichtbar für Verweise in der gleichen Klasse.

protected

Sichtbar für Verweise in der gleichen Klasse sowie in abgeleiteten Klassen.

public

Sichtbar für alle Verweise.

static

Gibt an, dass eine Eigenschaft zur Klasse und nicht zu Instanzen dieser Klasse gehört.

UserDefinedNamespace

Benutzerdefinierter Namespace-Name.

Namespace-Attribute zur Zugriffskontrolle

In ActionScript 3.0 stehen vier spezielle Attribute zur Verfügung, mit denen der Zugriff auf Eigenschaften kontrolliert werden kann, die in einer Klasse definiert sind: public, private, protected und internal.

Das Attribut public macht eine Eigenschaft im gesamten Skript sichtbar. Um beispielsweise eine Methode für Code außerhalb des Pakets verfügbar zu machen, müssen Sie sie mit dem Attribut public deklarieren. Dies gilt für jede Eigenschaft, unabhängig davon, ob sie mit dem Schlüsselwort var, const oder function deklariert wurde.

Das Attribut private macht eine Eigenschaft nur für aufrufende Objekte innerhalb der Klasse sichtbar, in der die Eigenschaft definiert wurde. Dieses Verhalten unterscheidet sich von dem des private-Attributs in ActionScript 2.0, das einer Unterklasse den Zugriff auf eine private Eigenschaft einer übergeordneten Klasse gestattete. Eine andere wesentliche Verhaltensänderung betrifft den Laufzeitzugriff. In ActionScript 2.0 verhinderte das Schlüsselwort private den Zugriff während der Kompilierung und wurde zur Laufzeit einfach umgangen. Dies ist in ActionScript 3.0 nicht mehr möglich. Auf Eigenschaften, die als private gekennzeichnet sind, kann weder während der Kompilierung noch zur Laufzeit zugegriffen werden.

Der folgende Code erstellt eine einfache Klasse namens „PrivateExample“ mit einer als „private“ deklarierten Variablen und versucht dann, von außerhalb der Klasse aus auf diese Variable zuzugreifen.

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. 

In ActionScript 3.0 führt der Versuch, mit dem Punktoperator auf eine als „private“ deklarierte Eigenschaft zuzugreifen (myExample.privVar), im strikten Modus zu einem Kompilierzeitfehler. Andernfalls tritt der Fehler zur Laufzeit auf, als ob Sie den Eigenschaften-Zugriffsoperator (myExample["privVar"]) verwenden.

In der folgenden Tabelle sind die Ergebnisse des versuchten Zugriffs auf eine als „private“ deklarierte Eigenschaft aufgeführt, die zu einer versiegelten (nicht dynamischen) Klasse gehört:

 

Strikter Modus

Standardmodus

Punktoperator (.)

Kompilierzeitfehler

Laufzeitfehler

Klammernoperator ([])

Laufzeitfehler

Laufzeitfehler

Bei Klassen, die mit dem dynamic-Attribut deklariert sind, führen Versuche, auf eine als „private“ deklarierte Variable zuzugreifen, nicht zu einem Laufzeitfehler. Stattdessen ist die Variable nicht sichtbar, sodass der Wert undefined zurückgegeben wird. Wenn Sie den Punktoperator jedoch im strikten Modus verwenden, tritt ein Kompilierzeitfehler auf. Der folgende Beispielcode entspricht dem vorangegangenen, außer dass die PrivateExample-Klasse als dynamische Klasse deklariert ist:

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

Anstatt einen Fehler zu erzeugen, geben dynamische Klassen im Allgemeinen den Wert undefined zurück, wenn Code außerhalb einer Klasse versucht, auf eine als „private“ deklarierte Eigenschaft zuzugreifen. Die folgende Tabelle zeigt, dass nur dann ein Fehler erzeugt wird, wenn im strikten Modus mit dem Punktoperator auf eine als „private“ deklarierte Eigenschaft zugegriffen wird:

 

Strikter Modus

Standardmodus

Punktoperator (.)

Kompilierzeitfehler

undefined

Klammernoperator ([])

undefined

undefined

Das in ActionScript 3.0 neu eingeführte Attribut protected macht eine Eigenschaft für aufrufende Objekte innerhalb der eigenen Klasse oder einer Unterklasse sichtbar. Anders ausgedrückt, eine als „protected“ deklarierte Eigenschaft steht innerhalb der eigenen Klasse oder in Klassen zur Verfügung, die sich in der Vererbungshierarchie unterhalb der eigenen Klasse befinden. Dies gilt unabhängig davon, ob sich die Unterklasse im gleichen oder in einem anderen Paket befindet.

Diese Funktionalität ähnelt dem private-Attribut in ActionScript 2.0. Das protected-Attribut aus ActionScript 3.0 ähnelt auch dem protected-Attribut in Java. Der Unterschied besteht darin, dass die Java-Version auch den Zugriff auf aufrufende Objekte im selben Paket ermöglicht. Das protected-Attribut eignet sich insbesondere dann, wenn Unterklassen eine Variable oder Methode erfordern, der Code jedoch außerhalb der Vererbungskette nicht sichtbar sein soll.

Das in ActionScript 3.0 neu eingeführte Attribut internal macht eine Eigenschaft für aufrufende Objekte innerhalb des eigenen Pakets sichtbar. Dies ist das Standardattribut für Code innerhalb eines Pakets. Es gilt für jede Eigenschaft, die keines der folgenden Attribute aufweist:

  • public

  • private

  • protected

  • ein benutzerdefinierter Namespace

Das internal-Attribut ähnelt der Standard-Zugriffskontrolle in Java, obwohl es in Java keinen expliziten Namen für diese Zugriffsebene gibt und sie nur durch Weglassen eines anderen Zugriffsmodifizierers erreicht werden kann. Mit dem Attribut internal in ActionScript 3.0 können Sie explizit festlegen, dass eine Eigenschaft nur für aufrufende Objekte innerhalb des eigenen Pakets sichtbar ist.

static-Attribut

Das static-Attribut, das mit Eigenschaften verwendet werden kann, die mit den Schlüsselwörtern var, const oder function deklariert wurden, ermöglicht Ihnen das Anhängen einer Eigenschaft an die Klasse anstatt an Instanzen der Klasse. Code, der sich außerhalb der Klasse befindet, muss statische Eigenschaften mit dem Klassennamen anstelle des Instanznamens aufrufen.

Statische Eigenschaften werden von Unterklassen nicht übernommen, aber die Eigenschaften sind Teil der Gültigkeitsbereichskette der Unterklasse. Dies bedeutet, dass eine statische Variable oder Methode im Unterklassenrumpf verwendet werden kann, ohne dass auf die Klasse verwiesen wird, in der sie definiert wurde.

Benutzerdefinierte Namespace-Attribute

Als Alternative zu den vordefinierten Attributen der Zugriffskontrolle können Sie einen benutzerdefinierten Namespace erstellen, der als Attribut verwendet werden soll. Es kann nur ein Namespace-Attribut pro Definition verwendet werden, und Sie können ein Namespace-Attribut nicht in Verbindung mit einem der Zugriffskontrollattribute (public, private, protected, internal) verwenden.

Variablen

Variablen können mit den Schlüsselwörtern var oder const deklariert werden. Mit dem Schlüsselwort var deklarierte Variablen können ihre Werte während der Ausführung eines Skript mehrmals ändern. Mit dem Schlüsselwort const deklarierte Variablen werden als Konstanten bezeichnet. Konstanten kann nur einmal ein Wert zugewiesen werden. Der Versuch, einer bereits initialisierten Konstanten einen neuen Wert zuzuweisen, führt zu einer Fehlermeldung.

Statische Variablen

Statische Variablen werden mit einer Kombination aus dem Schlüsselwort static und der Anweisung var oder der Anweisung const deklariert. Statische Variablen, die an eine Klasse und nicht an eine Instanz einer Klasse angehängt sind, eignen sich insbesondere zum Speichern und gemeinsamen Nutzen von Informationen, die für eine gesamte Objektklasse gelten. So können Sie eine statische Variable einsetzen, wenn Sie zählen möchten, wie oft eine Klasse instanziiert wurde, oder wenn der Höchstwert für zulässige Klasseninstanzen gespeichert werden soll.

Im folgenden Beispielcode werden eine totalCount-Variable (um die Anzahl der Klasseninstanziierungen zu verfolgen) und eine MAX_NUM-Konstante erstellt, in der die Höchstzahl an zulässigen Instanziierungen gespeichert wird. Die Variablen totalCount und MAX_NUM sind statische Variablen, da sie Werte enthalten, die für die gesamte Klasse und nicht für eine bestimmte Instanz gelten.

class StaticVars 
{ 
    public static var totalCount:int = 0; 
    public static const MAX_NUM:uint = 16; 
}

Code außerhalb der StaticVars-Klasse und einer ihrer Unterklassen kann nur über die Klasse selbst auf die Eigenschaften totalCount und MAX_NUM verweisen. Der folgende Code arbeitet korrekt:

trace(StaticVars.totalCount); // output: 0 
trace(StaticVars.MAX_NUM); // output: 16

Sie können nicht über die Instanz der Klasse auf statische Variablen zugreifen, daher gibt der folgende Code Fehlermeldungen zurück:

var myStaticVars:StaticVars = new StaticVars(); 
trace(myStaticVars.totalCount); // error 
trace(myStaticVars.MAX_NUM); // error

Mit den Schlüsselwörtern static und const deklarierte Variablen müssen zusammen mit der Konstantendeklaration initialisiert werden, wie es die StaticVars-Klasse für MAX_NUM durchführt. Sie können MAX_NUM innerhalb eines Konstruktors oder einer Instanzmethode keinen Wert zuweisen. Der folgende Code erzeugt eine Fehlermeldung, da es sich nicht um eine gültige Methode zum Initialisieren einer statischen Konstante handelt:

// !! Error to initialize static constant this way 
class StaticVars2 
{ 
    public static const UNIQUESORT:uint; 
    function initializeStatic():void 
    { 
        UNIQUESORT = 16; 
    } 
}

Instanzvariablen

Instanzvariablen enthalten Eigenschaften, die mit den Schlüsselwörtern var und const, aber ohne das Schlüsselwort static deklariert wurden. Instanzvariablen, die nicht an die gesamte Klasse, sondern an Klasseninstanzen angehängt werden, dienen unter anderem zum Speichern von Werten, die speziell für eine Instanz gelten. Beispielsweise verfügt die Array-Klasse über eine Instanzeigenschaft mit dem Namen length, die verschiedene Array-Elemente speichert, die eine bestimmte Instanz der Array-Klasse enthält.

Als var oder const deklarierte Instanzvariablen können in einer Unterklasse nicht überschrieben werden. Mit den get- und set-Methoden können Sie jedoch eine Funktionalität erreichen, die dem Überschreiben von Variablen ähnelt.

Methoden

Methoden sind Funktionen, die einen Teil einer Klassendefinition bilden. Nachdem eine Instanz der Klasse erstellt wurde, ist eine Methode an diese Instanz gebunden. Im Gegensatz zu einer außerhalb einer Klasse deklarierten Funktion kann eine Methode nicht außerhalb der Instanz verwendet werden, an die sie angefügt ist.

Methoden werden mit dem Schlüsselwort function definiert. Wie bei jeder Klasseneigenschaft können Sie jedes Klasseneigenschaftsattribut auf Methoden anwenden, einschließlich der Attribute „private“, „protected“, „public“, „internal“, „static“ oder eines benutzerdefinierten Namespace. Sie können eine Funktionsanweisung wie die folgende verwenden:

public function sampleFunction():String {}

Sie können auch eine Variable verwenden, der ein Funktionsausdruck zugewiesen wird. Dies wird im folgenden Beispiel gezeigt:

public var sampleFunction:Function = function () {}

In den meisten Fällen verwenden Sie aus den folgenden Gründen eine Funktionsanweisung anstelle eines Funktionsausdrucks:

  • Funktionsanweisungen sind kompakter und besser lesbar.

  • Funktionsanweisungen ermöglichen Ihnen das Verwenden der Schlüsselwörter override und final.

  • Funktionsanweisungen erstellen eine stärkere Bindung zwischen dem Bezeichner (also dem Namen der Funktion) und dem Code im Methodenrumpf. Der Wert einer Variablen kann mit einer Zuweisungsanweisung geändert werden, somit kann die Verbindung zwischen einer Variablen und ihrem Funktionsausdruck jederzeit aufgehoben werden. Sie können dieses Problem durch Deklarieren der Variablen mit const anstelle von var umgehen. Allerdings wird von dieser Vorgehensweise abgeraten, da sie den Code schwerer lesbar macht und das Verwenden der Schlüsselwörter override und final verhindert.

Ein Fall, bei dem Sie einen Funktionsausdruck verwenden, ist wenn Sie eine Funktion an das Prototypobjekt anhängen möchten.

Konstruktormethoden

Konstruktormethoden (manchmal auch als Konstruktoren bezeichnet) sind Funktionen, die den gleichen Namen wie die Klassen haben, in denen sie definiert wurden. Ein in eine Konstruktormethode aufgenommener Code wird immer dann ausgeführt, wenn eine Instanz der Klasse mit dem Schlüsselwort new erstellt wird. Im folgenden Beispielcode wird eine einfache Klasse namens „Example“ definiert, die eine Eigenschaft mit der Bezeichnung status enthält. Der Startwert der Variablen status ist in der Konstruktorfunktion festgelegt.

class Example 
{ 
    public var status:String; 
    public function Example() 
    { 
        status = "initialized"; 
    } 
} 
 
var myExample:Example = new Example(); 
trace(myExample.status); // output: initialized

Konstruktormethoden können nur öffentlich sein, aber die Verwendung des Attributs public ist optional. Sie können keinen der anderen Zugriffskontrollbezeichner wie private, protected oder internal für einen Konstruktor verwenden. Außerdem ist es nicht möglich, einen benutzerdefinierten Namespace mit einer Konstruktormethode zu verwenden.

Mit der Anweisung super() kann ein Konstruktor den Konstruktor der direkt übergeordneten Klasse aufrufen. Wenn der Konstruktor der übergeordneten Klasse nicht explizit aufgerufen wird, fügt der Compiler automatisch einen Aufruf vor der ersten Anweisung in den Konstruktorrumpf ein. Sie können die Methoden der übergeordneten Klasse auch mit dem Präfix super als Verweis auf die übergeordnete Klasse aufrufen. Wenn Sie sowohl super() als auch super im gleichen Konstruktorrumpf verwenden möchten, achten Sie darauf, zuerst super() aufzurufen. Andernfalls verhält sich der super-Verweis nicht wie erwartet. Außerdem muss der super()-Konstruktor vor allen throw- oder return-Anweisungen aufgerufen werden.

Im folgenden Beispielcode wird gezeigt, was geschieht, wenn Sie versuchen, den Verweis super vor dem Aufruf des super()-Konstruktors zu verwenden. Eine neue Klasse, „ExampleEx“, erweitert die Example-Klasse. Der ExampleEx-Konstruktor versucht, auf die in der übergeordneten Klasse definierte Statusvariable zuzugreifen, jedoch vor dem Aufruf von super(). Die trace()-Anweisung im ExampleEx-Konstruktor erzeugt den Wert null, da die status-Variable erst verfügbar ist, nachdem der super()-Konstruktor ausgeführt wurde.

class ExampleEx extends Example 
{ 
    public function ExampleEx() 
    { 
        trace(super.status); 
        super(); 
    } 
} 
 
var mySample:ExampleEx = new ExampleEx(); // output: null

Obwohl die return-Anweisung in einem Konstruktor zulässig ist, darf kein Wert zurückgegeben werden. Anders ausgedrückt, return-Anweisungen dürfen keine Ausdrücke oder Werte zugewiesen werden. Entsprechend dürfen auch Konstruktormethoden keine Werte zurückgeben. Dies bedeutet, dass kein Rückgabetyp angegeben werden kann.

Wenn Sie keine Konstruktormethode in Ihrer Klasse definieren, erstellt der Compiler automatisch einen leeren Konstruktor für Sie. Wenn Ihre Klasse eine andere Klasse erweitert, nimmt der Compiler einen super()-Aufruf in den erstellten Konstruktor auf.

Statische Methoden

Statische Methoden, die auch als Klassenmethoden bezeichnet werden, sind Methoden, die mit dem Schlüsselwort static deklariert werden. Statische Methoden, die an eine Klasse und nicht an eine Instanz einer Klasse angehängt werden, eignen sich insbesondere zur Kapselung von Funktionsmerkmalen, die sich auf etwas anderes auswirken als auf den Zustand einer bestimmten Instanz. Da statische Methoden an eine gesamte Klasse angehängt werden, kann nur über eine Klasse und nicht über die Instanz der Klasse auf statische Methoden zugegriffen werden.

Statische Methoden eignen sich besonders zur Kapselung von Funktionen, die sich nicht nur auf den Zustand von Klasseninstanzen auswirken. Anders ausgedrückt, eine Methode sollte statisch sein, wenn sie Funktionen bereitstellt, die sich nicht direkt auf den Wert einer Klasseninstanz auswirken. Beispielsweise verfügt die Date-Klasse über eine statische Methode mit der Bezeichnung parse(), die einen String in eine Zahl umwandelt. Die Methode ist statisch, da sie keine Auswirkungen auf eine einzelne Instanz der Klasse hat. Stattdessen arbeitet die Methode parse() mit einem String, der einen Datumswert darstellt, analysiert den String und gibt eine Zahl in dem Format zurück, das mit der internationalen Darstellung eines Date-Objekts kompatibel ist. Diese Methode ist keine Instanzmethode, da es keinen Sinn ergibt, die Methode auf eine Instanz der Date-Klasse anzuwenden.

Vergleichen Sie die statische Methode parse() mit einer der Instanzmethoden der Date-Klasse, wie z. B. getMonth(). Die getMonth()-Methode ist eine Instanzmethode, da sie direkt den Wert einer Instanz einbezieht, indem sie eine bestimmte Komponente (den Monat) der Date-Instanz abruft.

Da statische Methoden nicht an einzelne Instanzen gebunden sind, können die Schlüsselwörter this oder super nicht im Rumpf einer statischen Methode verwendet werden. Die Verweise this und super sind nur innerhalb des Kontextes der Instanzmethode gültig.

Im Gegensatz zu anderen klassenbasierten Programmiersprachen werden statische Methoden in ActionScript 3.0 nicht geerbt.

Instanzmethoden

Instanzmethoden sind Methoden, die ohne das Schlüsselwort static deklariert werden. Instanzmethoden, die an Instanzen einer Klasse und nicht an eine gesamte Klasse angehängt werden, eignen sich insbesondere zum Implementieren von Funktionen, die sich auf einzelne Instanzen einer Klasse auswirken. Beispielsweise enthält die Array-Klasse eine Instanzmethode namens sort(), die Array-Instanzen direkt einbezieht.

Innerhalb eines Instanzmethodenrumpfs sind sowohl statische als auch Instanzvariablen im Gültigkeitsbereich. Dies bedeutet, dass in der gleichen Klasse definierte Variablen mithilfe eines einfachen Bezeichners referenziert werden können. Beispielsweise erweitert die folgende Klasse, „CustomArray“, die Array-Klasse. Die CustomArray-Klasse definiert eine statische Variable namens arrayCountTotal, mit der die Gesamtzahl der Klasseninstanzen verfolgt wird, eine Instanzvariable namens arrayNumber, mit der die Reihenfolge verfolgt wird, in der die Instanzen erstellt werden, sowie eine Instanzmethode namens getPosition(), mit der die Werte dieser Variablen zurückgegeben werden.

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

Obwohl Code außerhalb der Klasse über das Klassenobjekt mit CustomArray.arrayCountTotal auf die statische Variable arrayCountTotal zugreifen muss, kann Code, der sich im Rumpf der getPosition()-Methode befindet, direkt auf die statische Variable arrayCountTotal verweisen. Dies gilt sogar für statische Variablen in übergeordneten Klassen. Obwohl statische Eigenschaften in ActionScript 3.0 nicht vererbt werden, befinden sich auch die statischen Eigenschaften in übergeordneten Klassen innerhalb des Gültigkeitsbereichs. Beispielsweise verfügt die Array-Klasse über einige statische Variablen, eine davon ist eine Konstante namens DESCENDING. Code, der sich in einer Array-Unterklasse befindet, kann mithilfe eines einfachen Bezeichners auf die statische Konstante DESCENDING zugreifen:

public class CustomArray extends Array 
{ 
    public function testStatic():void 
    { 
        trace(DESCENDING); // output: 2 
    } 
}

Der Wert des Verweises this im Rumpf einer Instanzmethode ist ein Verweis auf die Instanz, an die die Methode angefügt ist. Im folgenden Code wird veranschaulicht, dass der Verweis this auf die Instanz zeigt, in der die Methode enthalten ist:

class ThisTest 
{ 
    function thisValue():ThisTest 
    { 
        return this; 
    } 
} 
 
var myTest:ThisTest = new ThisTest(); 
trace(myTest.thisValue() == myTest); // output: true

Die Vererbung von Instanzmethoden kann mit den Schlüsselwörtern override und final gesteuert werden. Mit dem Attribut override können Sie eine geerbte Methode neu definieren, und mit dem Attribut final können Sie verhindern, dass Unterklassen eine Methode überschreiben.

get- und set-Accessormethoden

Mit den get- und set-Accessorfunktionen, die auch als getter und setter bezeichnet werden, können Sie bei der Programmierung an den Prinzipien des Ausblendens und der Kapselung von internen Daten festhalten, während gleichzeitig eine benutzerfreundliche Programmierschnittstelle für von Ihnen erstellte Klassen bereitgestellt wird. Mit get- und set-Funktionen bleiben Ihre Klasseneigenschaften privat in der Klasse, aber anderen Benutzern Ihrer Klasse wird der Zugriff auf diese Eigenschaften so gestattet, als ob sie auf eine Klassenvariable zugreifen, anstatt eine Klassenmethode aufzurufen.

Der Vorteil dieses Ansatzes liegt darin, dass Sie die traditionellen Accessorfunktionen mit ihren sperrigen Namen wie getPropertyName() und setPropertyName() vermeiden können. Ein weiterer Vorteil der get- und set-Methoden besteht darin, dass sie zwei öffentliche Funktionen für jede Eigenschaft vermeiden, die Lese- und Schreibzugriff gestatten.

Die folgende Beispielklasse mit der Bezeichnung „GetSet“ enthält ein get- und set-Accessorfunktionspaar namens publicAccess(), mit dem auf die private Variable namens privateProperty zugegriffen werden kann:

class GetSet 
{ 
    private var privateProperty:String; 
     
    public function get publicAccess():String 
    { 
        return privateProperty; 
    } 
     
    public function set publicAccess(setValue:String):void 
    { 
        privateProperty = setValue; 
    } 
}

Wenn Sie versuchen, direkt auf die privateProperty-Eigenschaft zuzugreifen, tritt ein Fehler auf:

var myGetSet:GetSet = new GetSet(); 
trace(myGetSet.privateProperty); // error occurs

Stattdessen verwendet ein Benutzer der GetSet-Klasse etwas, das eine Eigenschaft namens publicAccess zu sein scheint, in Wirklichkeit aber ein get- und set-Accessorfunktionspaar ist, das mit einer privaten Eigenschaft namens privateProperty arbeitet. Im folgenden Beispielcode wird die GetSet-Klasse instanziiert und dann der Wert von privateProperty mithilfe des öffentlichen Accessors publicAccess eingestellt:

var myGetSet:GetSet = new GetSet(); 
trace(myGetSet.publicAccess); // output: null 
myGetSet.publicAccess = "hello"; 
trace(myGetSet.publicAccess); // output: hello

Mit get- und set-Funktionen können auch die von einer übergeordneten Klasse übernommenen Eigenschaften überschrieben werden. Dies ist mit normalen Klassenmitgliedervariablen nicht möglich. Mit dem Schlüsselwort var deklarierte Klassenmitgliedervariablen können in einer Unterklasse nicht überschrieben werden. Eigenschaften, die mit get- und set-Funktionen erstellt wurden, weisen diese Einschränkung nicht auf. Für get- und set-Funktionen, die von einer übergeordneten Klasse geerbt wurden, können Sie das Attribut override verwenden.

Gebundene Methoden

Eine gebundene Methode, die manchmal auch als Methodenhülle (Method Closure) bezeichnet wird, ist im Grunde genommen eine Methode, die aus ihrer Instanz extrahiert wurde. Beispiele für gebundene Methoden sind Methoden, die als Argumente an eine Funktion übergeben oder als Werte von einer Funktion zurückgegeben werden. Gebundenen Methoden wurde in ActionScript 3.0 neu eingeführt. Sie ähneln in gewisser Weise einer Funktionshülle, da sie die lexikalische Umgebung auch dann beibehalten, wenn sie aus ihrer Instanz extrahiert wurden. Der wesentliche Unterschied zwischen einer gebundene Methode und einer Funktionshülle besteht jedoch darin, dass der Verweis this bei einer gebundenen Methode mit der Instanz verknüpft oder an die Instanz „gebunden“ bleibt, welche die Methode implementiert. Anders ausgedrückt, der Verweis this in einer gebundenen Methode zeigt immer auf das Ursprungsobjekt, das die Methode implementiert. Bei Funktionshüllen ist der this-Verweis generisch, d. h. er zeigt auf jedes Objekt, das der Funktion zum Zeitpunkt des Aufrufs zugewiesen ist.

Das Konzept der gebundenen Methoden ist für das Schlüsselwort this extrem wichtig. Zur Erinnerung: Das Schlüsselwort this stellt einen Verweis auf eine Methode des übergeordneten Objekts bereit. Die meisten ActionScript-Programmierer gehen davon aus, dass das this-Schlüsselwort immer die Klasse bzw. das Objekt mit der Definition einer Methode darstellt. Ohne Methodenbindung ist dies jedoch nicht immer richtig. In früheren Versionen von ActionScript referenzierte der Verweis this nicht immer die Instanz, welche die Methode implementierte. Wenn Methoden in ActionScript 2.0 aus einer Instanz extrahiert werden, ist nicht nur der Verweis this nicht an die Ursprungsinstanz gebunden, sondern auch die Mitgliedervariablen und -methoden der Instanzklasse stehen nicht zur Verfügung. Dies stellt in ActionScript 3.0 kein Problem dar, da gebundene Methoden automatisch erstellt werden, wenn Sie eine Methode als Parameter übergeben. Gebundene Methoden stellen sicher, dass das Schlüsselwort this immer auf das Objekt oder die Klasse verweist, in dem bzw. der eine Methode definiert ist.

Im folgenden Beispielcode wird eine Klasse namens „ThisTest“ erstellt, die eine Methode namens foo() enthält. Diese wiederum definiert eine gebundene Methode sowie eine Methode mit der Bezeichnung bar(), welche die gebundene Methode zurückgibt. Code außerhalb der Klasse erstellt eine Instanz der ThisTest-Klasse, ruft die Methode bar() auf und speichert den Rückgabewert in einer Variablen namens 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 */

Die letzten beiden Codezeilen zeigen, dass der Verweis this in der gebundenen Methode foo() noch immer auf eine Instanz der ThisTest-Klasse zeigt, obwohl der Verweis this in der Zeile direkt davor auf das globale Objekt zeigt. Darüber hinaus hat die in der gebundenen Methode gespeicherte Variable myFunc noch immer Zugriff auf die Mitgliedervariablen der ThisTest-Klasse. Wird derselbe Code in ActionScript 2.0 ausgeführt, stimmen beide Aufrufe von this überein und die Variable num ist undefined.

Ein Bereich, in dem sich die Einführung von gebundenen Methoden besonders bemerkbar macht, sind Ereignisprozeduren, da die Methode addEventListener() erfordert, dass Sie eine Funktion oder eine Methode als Argument übergeben.

Aufzählungen mit Klassen

Aufzählungen (Englisch „enumerations“) sind benutzerdefinierte Datentypen, die Sie zur Kapselung einer kleinen Wertegruppe erstellen. ActionScript 3.0 unterstützt keine besondere Aufzählungsfunktion, wie dies in C++ mit dem Schlüsselwort enum oder in Java mit der Enumeration-Schnittstelle der Fall ist. Sie können Aufzählungen jedoch mit Klassen und statischen Konstanten erstellen. Beispielsweise verwendet die PrintJob-Klasse in ActionScript 3.0 eine Aufzählung mit der Bezeichnung „PrintJobOrientation“, um die Werte "landscape" und "portrait" zu speichern. Dies wird im folgenden Code gezeigt:

public final class PrintJobOrientation 
{ 
    public static const LANDSCAPE:String = "landscape"; 
    public static const PORTRAIT:String = "portrait"; 
}

In der Standardeinstellung wird eine Aufzählungsklasse mit dem Attribut final deklariert, da es nicht erforderlich ist, die Klasse zu erweitern. Die Klasse enthält ausschließlich statische Mitglieder, daher müssen Sie keine Instanzen der Klasse erstellen. Stattdessen greifen Sie direkt über das Klassenobjekt auf die Aufzählungswerte zu. Dies wird im folgenden Codeausschnitt gezeigt:

var pj:PrintJob = new PrintJob(); 
if(pj.start()) 
{ 
    if (pj.orientation == PrintJobOrientation.PORTRAIT) 
    { 
        ... 
    } 
    ... 
}

Alle Aufzählungsklassen in ActionScript 3.0 enthalten nur Variablen des Typs „String“, „int“ oder „uint“. Der Vorteil bei der Verwendung von Aufzählungen anstelle von literalen Strings oder Zahlenwerten besteht darin, dass typografische Fehler in Aufzählungen leichter zu finden sind. Wenn Sie den Namen einer Aufzählung falsch eingeben, erzeugt der ActionScript-Compiler einen Fehler. Wenn Sie literale Werte verwenden, wird der Compiler ein falsch geschriebenes Wort nicht bemerken oder eine falsche Zahl verwenden. Im vorangegangenen Beispiel erzeugt der Compiler einen Fehler, wenn der Name der Aufzählungskonstanten falsch ist. Dies wird im folgenden Codeausschnitt gezeigt:

    if (pj.orientation == PrintJobOrientation.PORTRAI) // compiler error

Der Compiler erzeugt jedoch keinen Fehler, wenn Sie den literalen Wert eines Strings falsch schreiben:

    if (pj.orientation == "portrai") // no compiler error

Bei einer anderen Technik zur Erstellung von Aufzählungen wird ebenfalls eine separate Klasse mit statischen Eigenschaften für die Aufzählung definiert. Diese Technik unterscheidet sich jedoch insofern von der ersten, als dass jede statische Eigenschaft eine Instanz der Klasse anstelle eines Strings oder einer ganzen Zahl enthält. Im folgenden Beispielcode wird eine Aufzählungsklasse für die Tage der Woche erstellt:

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

Diese Technik wird von ActionScript 3.0 nicht genutzt, jedoch von vielen Entwicklern verwendet, die von der verbesserten Typüberprüfung profitieren möchten, die diese Technik bietet. Beispielsweise kann eine Methode, die einen Aufzählungswert zurückgibt, den Rückgabewert auf den Datentyp der Aufzählung einschränken. Der folgende Code enthält nicht nur eine Funktion, die einen Tag der Woche zurückgibt, sondern auch einen Funktionsaufruf, der den Datentyp der Aufzählung als Typanmerkung verwendet:

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

Sie können die Day-Klasse auch erweitern, sodass sie jedem Wochentag eine ganze Zahl zuweist und eine toString()-Methode bereitstellt, die eine Zeichenfolge mit dem Wochentag zurückgibt.

Eingebettete Bestandsklassen

Zum Darstellen von eingebettetem Bestand (Englisch „embedded assets“) verwendet ActionScript 3.0 spezielle Klassen, so genannte eingebettete Bestandsklassen. Ein eingebetteter Bestand ist ein Bestand, z. B. ein Sound, ein Bild oder eine Schriftart, der während der Kompilierung in einer SWF-Datei enthalten ist. Das Einbetten eines Bestands anstelle des dynamischen Ladens stellt sicher, dass der Bestand zur Laufzeit verfügbar ist. Es bedeutet jedoch auch eine größere SWF-Datei.

Verwenden eingebetteter Bestandsklassen in Flash Professional

Um einen Bestand einzubetten, platzieren Sie diesen zunächst in der Bibliothek einer FLA-Datei. Verwenden Sie anschließend die linkage-Eigenschaft des Bestands, um einen Namen für die eingebettete Bestandsklasse des Bestands anzugeben. Wenn im Klassenpfad keine Klasse mit diesem Namen vorhanden ist, wird automatisch eine entsprechende Klasse erstellt. Sie können dann eine Instanz der eingebetteten Bestandsklasse erstellen und alle Eigenschaften und Methoden verwenden, die für diese Klasse definiert oder von ihr geerbt wurden. Beispielsweise kann der folgende Code verwendet werden, um einen eingebetteten Sound wiederzugeben, der mit einer eingebetteten Bestandsklasse mit dem Namen „PianoMusic“ verknüpft ist:

var piano:PianoMusic = new PianoMusic(); 
var sndChannel:SoundChannel = piano.play();

Alternativ können Sie das [Embed]-Metadaten-Tag verwenden, um Bestände in einem Flash Professional-Projekt einzubetten wie nachstehend beschrieben. Wenn Sie das [Embed]-Metadaten-Tag in Ihrem Code einsetzen, verwendet Flash Professional den Flex-Compiler anstelle des Flash Professional-Compilers zur Kompilierung des Projekts.

Verwenden von eingebetteten Bestandsklassen mit dem Flex-Compiler

Wenn Sie Ihren Code mit dem Flex-Compiler kompilieren, verwenden Sie das [Embed]-Metadaten-Tag, um einen Bestand im ActionScript-Code einzubetten. Platzieren Sie den Bestand im Hauptquellordner oder einem anderen Ordner, der sich im Erstellungspfad Ihres Projekts befindet. Wenn der Flex-Compiler auf ein Embed-Metadaten-Tag trifft, erstellt er die eingebettete Bestandsklasse. Sie können auf die Klasse über eine Variable des Class-Datentyps zugreifen, die Sie unmittelbar nach dem [Embed]-Metadaten-Tag deklarieren. Der folgende Beispielcode bettet einen Sound namens „sound1.mp3“ ein und verwendet eine Variable namens soundCls zum Speichern eines Verweises auf die eingebettete Bestandsklasse, die diesem Sound zugewiesen ist. Anschließend erstellt der Beispielcode eine Instanz der eingebetteten Bestandsklasse und ruft die play()-Methode für diese Instanz auf:

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

Um das [Embed]-Metadaten-Tag in einem Flash Builder ActionScript-Projekt zu verwenden, importieren Sie die benötigten Klassen aus dem Flex-Framework. Zum Einbetten von Sounds importieren Sie beispielsweise die mx.core.SoundAsset-Klasse. Um die Flex-Architektur zu verwenden, nehmen Sie die Datei „framework.swc“ in den ActionScript-Erstellungspfad auf. Hierdurch vergrößert sich die SWF-Datei.

Adobe Flex

Alternativ können Sie einen Bestand in Flex auch mit der @Embed()-Direktive in einer MXML-Tag-Definition einbetten.