由於 ActionScript 3.0 是以舊版 ActionScript 為基礎所建立,瞭解 ActionScript 物件模型的演進情況可能會有幫助。ActionScript 最初是針對早期 Flash Professional 版本提供的簡單 Script 撰寫機制。後來,程式設計人員開始使用 ActionScript 建立日益複雜的應用程式。為了回應這些程式設計人員的需求,每一個後續版本都會有新增的語言功能,以便協助建立複雜的應用程式。
ActionScript 1.0
ActionScript 1.0 是用於 Flash Player 6 及更早版本中的語言版本。即使在這麼早期的開發階段,ActionScript 物件模型就是建立在以物件做為基礎資料類型的概念上。ActionScript 物件是具有一組「屬性」的複合資料類型;討論物件模型時,「屬性」一詞包含附加至物件的一切項目,如變數、函數或方法。
雖然這第一代 ActionScript 並不支援使用
class
關鍵字的類別定義,但可以使用稱為原型 (Prototype) 物件的特殊物件定義類別。ActionScript 1.0 原型語言跟 Java 和 C++ 類別語言不同:後兩者都使用
class
關鍵字建立抽象類別定義,以便實體化成具體物件,而 ActionScript 1.0 則是使用現有物件做為其它物件的模型 (或原型)。類別語言中的物件可以指向類別做為其範本,而原型語言中的物件卻是指向其它物件 (即其原型) 做為其範本。
若要在 ActionScript 1.0 中建立類別,必須為該類別定義建構函數。在 ActionScript 中,函數實際上就是物件,而不只是抽象定義。您所建立的建構函數是做為該類別之實體的原型物件。下列程式碼會建立名為 Shape 的類別,並定義一個名為
visible
的屬性,該屬性是預設為
true
:
// base class
function Shape() {}
// Create a property named visible.
Shape.prototype.visible = true;
此建構函數會定義您可以用
new
運算子實體化的 Shape 類別,如下所示:
myShape = new Shape();
就像
Shape()
建構函數物件可以做為 Shape 類別的實體原型,它也可以做為 Shape 的子類別 (也就是擴充 Shape 類別的其它類別) 之原型。
建立 Shape 類別的子類別要執行兩步驟程序。首先,定義類別的建構函數以建立該類別,如下所示:
// child class
function Circle(id, radius)
{
this.id = id;
this.radius = radius;
}
接下來,使用
new
運算子,以宣告 Shape 類別為 Circle 類別的原型。根據預設,您所建立的任何類別都會使用 Object 類別做為其原型,也就是說,
Circle.prototype
目前包含一般物件 (Object 類別的實體)。若要指定 Circle 的原型為 Shape 而不是 Object,請使用下列程式碼變更
Circle.prototype
的值,讓它包含 Shape 物件,而不是包含一般物件:
// Make Circle a subclass of Shape.
Circle.prototype = new Shape();
Shape 類別和 Circle 類別現在會以繼承關係連結成一體,這關係一般稱為「原型鏈」。下圖可說明原型鏈中的關係:
每一個原型鏈尾端的基底類別都是 Object 類別。Object 類別包含名為
Object.prototype
的靜態屬性,它指向 ActionScript 1.0 建立之所有物件的基底原型物件。範例原型鏈中的下一個物件是 Shape 物件。這是因為
Shape.prototype
屬性從未明確地設定,因此它仍然保存一般物件 (Object 類別的實體)。這個鏈中最後一個連結是 Circle 類別,它是連結至其原型 - Shape 類別 (
Circle.prototype
原型保存了 Shape 物件)。
如果您建立 Circle 類別的實體 (如同下列範例一樣),此實體會繼承 Circle 類別的原型鏈:
// Create an instance of the Circle class.
myCircle = new Circle();
不知您是否還記得,範例包含名為
visible
的屬性做為 Shape 類別的成員。在這個範例中,
visible
屬性不是
myCircle
物件的一部分,而只是做為 Shape 物件的成員,然而下列程式碼行卻輸出
true
:
trace(myCircle.visible); // output: true
執行階段只要順著原型鏈往上走,就能查明是
myCircle
物件繼承了
visible
屬性。執行此程式碼時,執行階段會先搜尋
myCircle
物件的所有屬性,尋找名為
visible
的屬性,但找不到這個屬性。接著,它就在
Circle.prototype
物件中尋找,但還是找不到名為
visible
的屬性。繼續順著原型鏈往上走,它終於找到在
Shape.prototype
物件上定義的
visible
屬性,並輸出該屬性的值。
由於想要盡可能地簡單明瞭,因此本節內容省略了原型鏈的許多細節和錯綜複雜的關係。而是將重點放在提供足夠資訊,希望能協助您瞭解 ActionScript 3.0 物件模型。
ActionScript 2.0
ActionScript 2.0 導入新的關鍵字,如
class
、
extends
、
public
和
private
,可讓您以使用 Java 和 C++ 等類別語言者所熟悉的方式來定義類別。請務必要了解,基礎繼承機制在 ActionScript 1.0 與 ActionScript 2.0 之間並沒有任何改變,ActionScript 2.0 只是加了新語法,可供定義類別而已。原型鏈在這兩版語言中的運作方式完全一樣。
由 ActionScript 2.0 導入的新語法 (如下列摘錄所示),讓您能夠以許多程式設計人員覺得更為直覺的方式來定義類別:
// base class
class Shape
{
var visible:Boolean = true;
}
請注意,ActionScript 2.0 也導入類型附註,可用來進行編譯階段類型檢查。如此一來,您便可以宣告上一個範例中的
visible
屬性應該只包含 Boolean 值;新的
extends
關鍵字也簡化了建立子類別的程序。在下列範例中,ActionScript 1.0 中必須要有兩個步驟的程序,而使用
extends
關鍵字只需一個步驟就可完成:
// child class
class Circle extends Shape
{
var id:Number;
var radius:Number;
function Circle(id, radius)
{
this.id = id;
this.radius = radius;
}
}
建構函式現在是宣告為類別定義的一部分,而類別屬性
id
和
radius
都必須明確地進行宣告。
ActionScript 2.0 也新增介面定義的支援,可讓您利用正式為物件間通訊定義的通訊協定,更進一步修改您的物件導向程式。