|
Flash CS4-Ressourcen |
MethodenMethoden 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 Klasseneigenschaften können Sie auch die Attribute von Klasseneigenschaften auf Methoden anwenden, einschließlich „private“, „protected“, „public“, „internal“, „static“ oder eines benutzerdefinierten Namespace. Sie können dazu eine function-Anweisung 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 werden Sie aus den folgenden Gründen eine Funktionsanweisung anstelle eines Funktionsausdrucks verwenden:
Ein Fall, bei dem Sie einen Funktionsausdruck verwenden, ist wenn Sie eine Funktion an das Prototypobjekt anhängen möchten. Weitere Informationen finden Sie unter Prototypobjekt. KonstruktormethodenKonstruktormethoden (manchmal auch einfach 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 Verweis super 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 MethodenStatische 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. Weitere Informationen finden Sie unter Nicht geerbte statische Eigenschaften. InstanzmethodenInstanzmethoden 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 verweisen 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 verweisen: 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. Weitere Informationen finden Sie unter Überschreiben von Methoden. get- und set-AccessormethodenMit 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 Eigenschaft privateProperty 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 MethodenEine 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 Verweis this 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 Schlüsselwort this immer auf die Klasse bzw. das Objekt verweist, die bzw. das die Definition einer Methode enthält. 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. Weitere Informationen finden Sie im Abschnitt zu als Methode einer Klasse definierten Listener-Funktionen unter Ereignis-Listener. |