Flash CS3 文件 |
|||
| ActionScript 3.0 程式設計 > 使用 ActionScript 設計物件導向程式 > 類別 > 方法 | |||
方法是類別定義之一部分的函數,一旦建立了類別的實體之後,方法即繫結至該實體。方法與在類別之外宣告的函數不同,它不能離開所附加之實體單獨使用。
方法是使用 function 關鍵字定義的。您可以使用函數陳述式,如下所示:
public function sampleFunction():String {}
也可以使用您指定了函數運算式的變數,如下所示:
public var sampleFunction:Function = function () {}
一般來說,您要使用函數陳述式,而不要使用函數運算式,理由如下:
override 和 final 關鍵字。如需詳細資訊,請參閱覆寫方法。const (而不是用 var) 宣告變數的方式來解決這個問題,但一般並不認為這種技巧是最佳作法,因為它會讓程式碼很難閱讀,而且無法使用 override 和 final 關鍵字。但是有一種情況您必須使用函數運算式,就是當您選擇將函數附加至原型件時。如需詳細資訊,請參閱原型 (Prototype) 物件。
建構函式方法有時就直接稱為「建構函式」,是與它們的定義類別共用相同名稱的函數。只要類別的實體以 new 關鍵字建立時,就會執行您包含在建構函式方法中的任何程式碼。例如,下列程式碼會定義名為 Example 的簡單類別,其中只包含一個名為 status 的屬性,status 變數的初始值是在建構函數中設定。
class Example
{
public var status:String;
public function Example()
{
status = "initialized";
}
}
var myExample:Example = new Example();
trace(myExample.status); // 輸出:initialized
建構函式方法只能是公用的,但是否使用 public 特質卻是選擇性的。您不能在建構函式上使用任何其它存取控制指定字,包括 private、protected 或 internal。您也不能使用具有建構函式方法的使用者定義命名空間。
建構函式可以使用 super() 陳述式,明確呼叫其直屬父類別的建構函式;如果沒有明確地呼叫父類別建構函式,編譯器會自動在建構函式主體的第一個陳述式之前插入呼叫。您也可以使用 super 前置詞做為父類別的參考,呼叫父類別的方法。若決定在相同的建構函式主體中,同時使用 super() 和 super,一定要先呼叫 super();否則,super 參考將不會表現出預期的行為方式。super() 建構函式也應該在任何 throw 或 return 陳述式之前進行呼叫。
下列範例會示範,若嘗試在呼叫 super() 建構函式之前,使用 super 參考,所發生的情況。新類別 ExampleEx 會擴充 Example 類別,ExampleEx 建搆函式會嘗試存取定義於其父類別的狀態變數,但會在呼叫 super() 之前進行。在 ExampleEx 建構函式之內的 trace() 陳述式會產生 null 值,因為 status 變數要在執行 super() 建構函式之後才能使用。
class ExampleEx extends Example
{
public function ExampleEx()
{
trace(super.status);
super();
}
}
var mySample:ExampleEx = new ExampleEx(); // 輸出:null
雖然在建構函式之內使用 return 陳述式是合法的,但卻不允許傳回值;換句話說,return 陳述式絕對不能有相關聯的運算式或值,因此,建構函式方法也不允許傳回值,也就是說,無法指定任何傳回類型。
若不在類別中定義建構函式方法,編譯器將自動為您建立空白的建構函式。若您的類別擴充另一個類別,編譯器將會在所產生的建構函式中包含 super() 呼叫。
靜態方法也稱為「類別方法」,是以 static 關鍵字宣告的方法。靜態方法是附加至類別而不是附加至類別的實體,適用於封裝影響個別實體狀態以外的功能。由於靜態方法是附加至類別整體,靜態方法只能透過類別存取,而無法透過類別的實體存取。
靜態方法適用於封裝不限於影響類別實體狀態的功能;換句話說,若方法提供的功能不會直接影響類別實體的功能,則方法應該是靜態的。例如,Date 類別具有名為 parse() 的靜態方法,它接受字串並轉換成數字;方法是靜態的,因為它不會影響類別的個別實體,而是由 parse() 方法接受代表日期值的字串,解析該字串,然後以與 Date 物件之內部形式相容的格式傳回數字。這個方法不是實體方法,因為將此方法套用至 Date 類別的實體沒有意義。
將靜態 parse() 方法與 Date 類別的其中一個實體方法,例如 getMonth(),對照比較;getMonth() 方法是實體方法,因為它是透過擷取 Date 實體的特定組件 (月份),直接在實體的值上運作。
因為靜態方法並不與個別實體繫結,您不能在靜態方法的主體之中使用關鍵字 this 或 super;this 參考和 super 參考都是只在實體方法的內容之中才有意義。
靜態方法與其它以類別為基礎的程式設計語言不同,在 ActionScript 3.0 中的靜態方法是不繼承的。如需詳細資訊,請參閱靜態屬性不繼承。
實體方法是不使用 static 關鍵字宣告的方法。實體方法是附加至類別的實體而不是類別整體,適用於實作會影響類別之個別實體的功能。例如,Array 類別包含名為 sort() 的實體方法,它是直接在 Array 實體上運作。
在實體方法的主體之內,靜態和實體變數都在範圍中,也就是說,在相同類別中定義的變數可以使用簡單的識別名稱進行參考。例如,下列類別 CustomArray 會擴充 Array 類別,CustomArray 類別會定義名為 arrayCountTotal 的靜態變數以追蹤類別實體的總數,定義名為 arrayNumber 的實體變數追蹤實體建立順序,以及名為 getPosition() 的實體方法傳回這些變數值。
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);
}
}
雖然類別之外的程式碼必須使用 CustomArray.arrayCountTotal,透過類別物件參考 arrayCountTotal 靜態變數,位於 getPosition() 方法主體之內的程式碼則可以直接參考 arrayCountTotal 靜態變數。即使是在父類別中的靜態變數也是如此。雖然靜態屬性在 ActionScript 3.0 中並不繼承,但父類別中的靜態屬性卻是在範圍中。例如,Array 類別有一些靜態變數,其中一個是名為 DESCENDING 的常數;位於 Array 子類別中的程式碼可以使用簡單的識別名稱,參考靜態常數 DESCENDING。
public class CustomArray extends Array
{
public function testStatic():void
{
trace(DESCENDING); // 輸出:2
}
}
實體方法主體之中 this 參考的值是附加方法之實體的參考。下列程式碼示範,this 參考指向包含該方法的實體:
class ThisTest
{
function thisValue():ThisTest
{
return this;
}
}
var myTest:ThisTest = new ThisTest();
trace(myTest.thisValue() == myTest); // 輸出:true
實體方法的繼承可以用 override 和 final 關鍵字加以控制;您可以使用 override 特質,重新定義已繼承的方法,而用 final 特質防止子類別覆寫方法。如需詳細資訊,請參閱覆寫方法。
Get 和 set 存取子函數也稱為 getter 和 setter,可以讓您在為所建立類別提供容易使用之程式設計介面的同時,也遵守資訊隱藏和封裝的程式設計原則。Get 和 set 函數可以讓您將類別屬性保持為類別私有,但可以讓類別的使用者以存取類別變數的方式來存取這些屬性,而不是呼叫類別方法來存取。
這種作法的優點是:可以讓您避免名稱大而無當的傳統存取子函數,例如 getPropertyName() 和 setPropertyName()。使用 getter 和 setter 的另一項好處是:可以避免每一個屬性都具有同時允許讀取及寫入存取的兩個公用外表的函數。
下列範例類別名為 GetSet,包括名為 publicAccess() 的 get 和 set 存取子函數,可讓您存取名為 privateProperty 的私有變數:
class GetSet
{
private var privateProperty:String;
public function get publicAccess():String
{
return privateProperty;
}
public function set publicAccess(setValue:String):void
{
privateProperty = setValue;
}
}
若嘗試直接存取 privateProperty 屬性,將會導致錯誤,如下所示:
var myGetSet:GetSet = new GetSet(); trace(myGetSet.privateProperty); // 發生錯誤
GetSet 類別的使用者則會使用看起來像名為 publicAccess 的屬性,但其實是一對 get 和 set 存取子函數,在名為 privateProperty 私有屬性上運作。下列範例會將 GetSet 類別實體化,然後使用名為 publicAccess 的公用存取子設定 privateProperty 的值:
var myGetSet:GetSet = new GetSet(); trace(myGetSet.publicAccess); // 輸出:null myGetSet.publicAccess = "hello"; trace(myGetSet.publicAccess); // 輸出:hello
Getter 和 setter 函數也可以讓您覆寫繼承自父類別的屬性,這是使用一般類別成員變數時不可能執行的作業。使用 var 關鍵字宣告的類別成員變數無法在子類別中加以覆寫;但是使用 getter 和 setter 函數建立的屬性卻沒有這項限制。您可以在繼承自父類別的 getter 和 setter 函數上使用 override 特質。
繫結方法有時稱為「方法結束項」,其實就是自方法實體擷取的方法。繫結方法的範例包括傳遞給函數做為引數的方法,或從函數傳回做為值的方法。繫結方法是 ActionScript 3.0 中新增的方法,類似於函數結束項,即使自方法實體擷取時都會保留其語彙環境。但是,繫結方法與函數結束項之間最主要的差異是:繫結方法的 this 參考會保持連結 (或稱為繫結) 至實作方法的實體,換句話說,繫結方法中的 this 參考永遠都指向實作方法的原始物件;而函數結束項的 this 參考則是一般參考,也就是說,它會指向叫用時與函數相關聯的任何物件。
若使用 this 關鍵字,則一定要瞭解繫結方法。請回想 this 關鍵字提供方法之父物件的參考,大部分 ActionScript 程式設計人員都會預期 this 關鍵字永遠都指向包含方法之定義的物件或類別;但是若沒有方法繫結,則不可能永遠都是如此。例如,在舊版 ActionScript 中,this 參考就不是永遠都指向實作方法的實體。在 ActionScript 2.0 中,當方法是從實體中擷取時,不但 this 參考不繫結至原始實體,成員變數和實體類別的方法也無法使用;在 ActionScript 3.0 中這不是問題,因為當您傳遞方法做為參數時,會自動建立繫結方法,繫結方法會確保 this 關鍵字永遠參考定義方法的物件或類別。
下列程式碼會定義名為 ThisTest 的類別,其中包含定義繫結方法而名為 foo() 的方法,以及傳回繫結方法而名為 bar() 的方法;類別外部的程式碼會建立 ThisTest 類別的實體,呼叫 bar() 方法,然後將值儲存在名為 myFunc 的變數中。
class ThisTest
{
private var num:Number = 3;
function foo():void // 定義的繫結方法
{
trace("foo's this: " + this);
trace("num: " + num);
}
function bar():Function
{
return foo; // 傳回的繫結方法
}
}
var myTest:ThisTest = new ThisTest();
var myFunc:Function = myTest.bar();
trace(this); // 輸出:[物件全域]
myFunc();
/* 輸出:
foo 的 this:[物件 ThisTest]
輸出:數字:3 */
程式碼的最後兩行會示範,即使該程式碼行中就在它之前的 this 參考指向全域物件,繫結方法 foo() 中的 this 參考仍然指向 ThisTest 類別的實體;而且,儲存在 myFunc 變數中的繫結方法也仍然可以存取 ThisTest 類別的成員變數。如果在 ActionScript 2.0 中執行相同的程式碼,this 參考會相符,但 num 變數會成為 undefined。
加上繫結方法最顯著之處與事件處理常式相關,因為 addEventListener() 方法會要求您傳遞函數或方法做為引數。如需詳細資訊,請參閱定義為類別方法的偵聽程式函數。
Flash CS3
目前頁面: http://livedocs.adobe.com/flash/9.0_tw/main/00000064.html