Eftersom ActionScript 3.0 bygger på tidigare versioner av ActionScript bör du känna till hur ActionScript-objektmodellen har utvecklats. ActionScript började som en enkel skriptfunktion för tidiga versioner av Flash Professional. Programmerarna började efterhand bygga mera komplexa program med ActionScript. Som svar på deras behov har efterföljande versioner fått nya språkfunktioner som förenklar komplexa program.
ActionScript 1.0
ActionScript 1.0 är den version av språket som används i Flash Player 6 och tidigare versioner. Även i detta tidiga utvecklingsstadium var ActionScript-objektmodellen baserad på konceptet med objekt som fundamental datatyp. Ett ActionScript-objekt är en sammansatt datatyp med en grupp
egenskaper
. När objektmodellen beskrivs ingår i termen
egenskaper
allt som bifogats till ett objekt, till exempel variabler, funktioner och metoder.
Även om den första generationen ActionScript inte stöder definitionen av klasser med nyckelordet
class
, kan du definiera en klass med ett särskilt objekt som kallas prototypobjekt. I stället för att använda nyckelordet
class
för att skapa en abstrakt klassdefinition som du instansierar till konkreta objekt, som du gör i klassbaserade språk som Java och C++, använder prototypbaserade språk som ActionScript 1.0 ett befintligt objekt som modell (eller prototyp) för andra objekt. Medan objekt i ett klassbaserat språk kan peka på en klass som fungerar som mall, pekar objekt i ett prototypbaserat språk på ett annat objekt, prototypen, som fungerar som mall.
Om du vill skapa en klass i ActionScript 1.0 definierar du en konstruktorfunktion för denna klass. I ActionScript är funktioner verkliga objekt och inte bara abstrakta definitioner. Konstruktorfunktionen som du skapar fungerar som prototypobjekt för förekomster av den här klassen. I följande kod skapas klassen Shape och definieras egenskapen
visible
som har värdet
true
som standard:
// base class
function Shape() {}
// Create a property named visible.
Shape.prototype.visible = true;
Den här konstruktorfunktionen definierar klassen Shape som du kan instansiera med operatorn
new
:
myShape = new Shape();
På samma sätt som konstruktorfunktionsobjektet
Shape()
fungerar som prototyp för förekomster av klassen Shape, kan det också fungera som prototyp för underklasser till Shape, d.v.s. andra klasser som utökar klassen Shape.
Att skapa en klass som är underklass till klassen Shape är en tvåstegsprocess. Först definierar du en konstruktorfunktion för klassen:
// child class
function Circle(id, radius)
{
this.id = id;
this.radius = radius;
}
Sedan använder du operatorn
new
för att deklarera att klassen Shape är prototyp för klassen Circle. Som standard används klassen Object som prototyp för alla klasser du skapar, vilket betyder att
Circle.prototyp
innehåller ett generiskt objekt (en förekomst av klassen Object). Om du vill ange att Circles prototyp är Shape och inte Object använder du följande kod för att ändra värdet för
Circle.prototyp
så att det innehåller ett Shape-objekt i stället för ett generiskt objekt:
// Make Circle a subclass of Shape.
Circle.prototype = new Shape();
Klassen Shape och Circle har nu kopplats ihop i en arvsrelation som kallas
prototypkedja
. Bilden visar relationen i en prototypkedja:
Basklassen i slutet av alla prototypkedjor är klassen Object. Klassen Object innehåller den statiska egenskapen
Object.prototype
, som pekar på basprototypsobjektet för alla objekt som skapas i ActionScript 1.0. Nästa objekt i prototypkedjan är objektet Shape. Detta beror på att egenskapen
Shape.prototype
aldrig angavs explicit, och den innehåller fortfarande ett generiskt objekt (en förekomst av klassen Object). Den sista länken i kedjan är klassen Circle som är kopplad till sin prototyp, klassen Shape (egenskapen
Circle.prototype
innehåller ett Shape-objekt).
Om du skapar en instans av klassen Circle, som i följande exempel, ärver instansen prototypkedjan för klassen Circle:
// Create an instance of the Circle class.
myCircle = new Circle();
Kom ihåg att exemplet också innehöll egenskapen
visible
som medlem i klassen Shape. I det här exemplet finns egenskapen
visible
inte som en del av objektet
myCircle
, utan bara som medlem i objektet Shape, och ändå returnerar följande kodrad
true
:
trace(myCircle.visible); // output: true
Körningsmiljön kan fastställa att objektet
myCircle
ärver egenskapen
visible
genom att gå upp i prototypkedjan. När den här koden körs genomsöks först egenskaperna för objektet
myCircle
efter egenskapen
visible
, men utan att hitta den. Därefter genomsöks objektet
Circle.prototype
, men fortfarande hittas inte egenskapen
visible
. Efterhand som sökningen rör sig uppåt i prototypkedjan hittas egenskapen
visible
, som definierats för objektet
Shape.prototype
, och värdet för egenskapen matas ut.
För enkelhets skull utelämnas många av de invecklade detaljerna kring prototypkedjan. Målet är i stället att ge tillräckligt mycket information för att ge en förståelse för objektmodellen i ActionScript 3.0.
ActionScript 2.0
ActionScript 2.0 innehåller nya nyckelord som
class
,
extends
,
public
och
private
, som gör att du kan definiera klasser på ett sätt som är bekant för alla som arbetar med klassbaserade språk som Java och C++. Du bör känna till att den underliggande arvsmekanismen inte ändrats mellan ActionScript 1.0 och ActionScript 2.0. I ActionScript 2.0 har bara infogats ny syntax för klassdefinition. Prototypkedjan fungerar på samma sätt i båda språkversionerna.
Med den nya syntaxen som introducerades i ActionScript 2.0 kan du definiera klasser på ett mera intuitivt sätt, vilket visas i följande utdrag:
// base class
class Shape
{
var visible:Boolean = true;
}
Observera att ActionScript 2.0 också innehåller typanteckningar som ska användas för typkontroll vid kompilering. Du kan då deklarera att egenskapen
visible
i föregående exempel ska innehålla bara ett booleskt värde. Med det nya nyckelordet
extends
förenklas också processen att skapa en underklass. I följande exempel har tvåstegsprocessen som är nödvändig i ActionScript 1.0 utförts i ett steg med nyckelordet
extends
.
// child class
class Circle extends Shape
{
var id:Number;
var radius:Number;
function Circle(id, radius)
{
this.id = id;
this.radius = radius;
}
}
Konstruktorn deklareras nu som en del av klassdefinitionen, och klassegenskaperna
id
och
radius
måste också deklareras explicit.
ActionScript 2.0 har också stöd för definition av gränssnitt vilket gör att du ytterligare kan förfina dina objektorienterade program med formellt definierade protokoll för kommunikation mellan objekt.