Flash CS3 文件 |
|||
| ActionScript 3.0 程式設計 > ActionScript 語言和語法 > 套件和命名空間 > 套件 | |||
在 ActionScript 3.0 中,套件都是用命名空間實作,但並非與命名空間同義。宣告套件時,是明確地建立特殊類型的命名空間,保證在編譯階段為已知;而命名空間雖然明確建立,卻並不一定保證能在編譯階段為已知。
下列範例會使用 package 指令,建立簡單的套件,其中包含一個類別:
package samples
{
public class SampleCode
{
public var sampleGreeting:String;
public function sampleFunction()
{
trace(sampleGreeting + " from sampleFunction()");
}
}
}
在此範例中的類別名稱是 SampleCode。由於此類別是在 samples 套件內,因此編譯器會在編譯階段自動限定類別名稱,成為完整名稱:samples.SampleCode。編譯器也會限定任何屬性或方法的名稱,讓 sampleGreeting 和 sampleFunction() 分別成為 samples.SampleCode.sampleGreeting 和 samples.SampleCode.sampleFunction()。
許多開發人員,尤其是具有 Java 程式設計背景的開發人員,可能會選擇只將類別放置於套件的最高階。但是 ActionScript 3.0 不但支援位於套件最高階的類別,也支援變數、函數,甚至也支援陳述式:這項功能的一個進階用法是在套件最高階定義命名空間,讓它能夠供該套件中的所有類別使用。但是請注意,套件最高階只允許兩個存取指定字 public 和 internal。與 Java 不同,ActionScript 3.0 不支援巢狀類別,也不支援私有類別,而 Java 允許您將巢狀類別宣告為私有。
但是在其它許多方面,ActionScript 3.0 套件與 Java 程式設計語言中的套件很類似。在上一個範例中您可以看到,完整的套件參考是使用點運算子 (.) 來表示,在 Java 中也一樣。您可以使用套件將程式碼組織成直覺式的階層結構,供其他程式設計人員使用。如此可經由允許您自行建立套件與他人共享,並可在您的程式碼中使用他人建立的套件,對共享程式碼方面來說頗有助益。
使用套件也有助確保您所使用的識別名稱為唯一,而不會與其它識別名稱相衝突。事實上,有些人認為這是套件最大的好處。例如,兩個程式設計人員想要彼此共享程式碼,便可以各自建立名為 SampleCode 的類別。若沒有套件,就會造成名稱衝突,而且唯一的解決辦法就是重新命名其中一個類別;但是有了套件,名稱衝突很容易避免,只要將其中一個類別命名為唯一的名稱並放在套件中 (最好是兩個同時做),便可解決。
您也可以在套件名稱中包含嵌入的點,以建立巢狀套件;如此可以讓您建立套件的階層式組織。最好的範例是由 Flash Player API 提供的 flash.xml 套件,flash.xml 套件是以巢狀方式嵌入於 flash 套件之中。
flash.xml 套件包含舊版 ActionScript 中所使用的舊版 XML 解析器,現在位於 flash.xml 套件內的其中一個原因是:舊版 XML 類別的名稱與新版 XML 類別名稱衝突,新版類別會實作 ActionScript 3.0 中所提供使用的 XML for ECMAScript (E4X) 規格功能。
雖然將舊版 XML 類別移入套件中是很好的開始,但多半的舊版 XML 類別使用者會匯入 flash.xml 套件,因此除非您記得永遠都使用舊版 XML 類別的完整名稱 (flash.xml.XML),否則這樣還是會產生相同的名稱衝突。為了避免這種情況,舊版 XML 類別現在命名為 XMLDocument,如下列範例所示:
package flash.xml{class XMLDocument {}class XMLNode {}class XMLSocket {}}
大部分 Flash Player API 都是在 flash 套件之下加以組織。例如,flash.display 套件包含顯示清單 API,而 flash.events 套件則包含新的事件模式。
ActionScript 3.0 在組織套件、類別和來源檔案的方式上,提供相當大的彈性。舊版 ActionScript 對每個來源檔案只允許一個類別,而且要求來源檔案的名稱與類別名稱相符。ActionScript 3.0 則可以讓您在一個來源檔案中包含多個類別,但每個檔案中只有一個類別可供該檔案外部的程式碼使用。也就是說,每個檔案中有一個類別可以在套件宣告之中進行宣告。您必須在套件定義之外宣告其它任何類別,而讓位於來源檔案之外的程式碼無法看見這些類別。在套件定義之內宣告的類別名稱必須與來源檔案的名稱相符。
ActionScript 3.0 在宣告套件的方式上,也提供更大的彈性。在前一版的 ActionScript 中,套件只代表放置來源檔案的目錄,且不是用 package 陳述式宣告套件,而是在類別宣告中包含套件名稱,做為完整類別名稱的一部分。雖然套件仍然代表 ActionScript 3.0 中的目錄,但套件可以包含的不只是類別而已。在 ActionScript 3.0 中是使用 package 陳述式宣告套件。也就是說,您也可以在套件最高階宣告變數、函數和命名空間,甚至可以在套件最高階納入可執行陳述式。若確實在套件最高階宣告變數、函數或命名空間,則在該階層唯一可用的特質是 public 和 internal,而且每個檔案只有一個套件層級宣告可以使用 public 屬性,不管該宣告是類別、變數、函數或命名空間都可以。
套件對組織程式碼及防止名稱衝突都很有用。請勿混淆了套件的概念與不相關的類別繼承概念。位於相同套件中的兩個類別將會有相同的命名空間,但彼此不一定會在其它任何方面相關;同樣地,巢狀套件與其父套件也可能沒有任何語意關聯性。
若要使用位於套件中的類別,您必須匯入套件或特定的類別。這與 ActionScript 2.0 不同,在該版本中匯入類別是選擇性的。
例如,請考慮本章前文內容中的 SampleCode 類別範例。若類別位於名為 samples 的套件中,您必須先使用下列其中一項 import 陳述式,才能使用 SampleCode 類別:
import samples.*;
或
import samples.SampleCode;
一般來說,import 陳述式應該盡可能明確。若想要只使用 samples 套件的 SampleCode 類別,應該只匯入 SampleCode 類別,而不是匯入類別所屬的整個套件。匯入整個套件可能會導致無法預期的名稱衝突。
您也必須將定義套件或類別的原始碼放入「類別路徑」中。類別路徑是使用者定義的清單,可決定編譯器所要搜尋匯入套件及類別的本機目錄路徑。類別路徑有時也稱為「組建路徑」或「來源路徑」。
在您正確匯入類別或套件之後,就可以使用類別的完整名稱 (samples.SampleCode),也可以僅使用類別名稱本身 (SampleCode)。
在以完全相同的名稱命名類別、方法或屬性而形成模棱兩可的程式碼時,完整名稱會很有用,但是若用於所有識別名稱,則可能會很難管理。例如,在實體化 SampleCode 類別實體時,使用完整名稱會造成冗長的程式碼:
var mySample:samples.SampleCode = new samples.SampleCode();
隨著巢狀套件的階層增加,程式碼的可讀性也跟著降低。在您確信模棱兩可的識別名稱不會成為問題時,可以使用簡單的識別名稱,讓程式碼更易於閱讀。例如,若只使用類別識別名稱,則實體化 SampleCode 類別的新實體就不致於太過冗長:
var mySample:SampleCode = new SampleCode();
若嘗試使用識別名稱,而並未先匯入適當的套件或類別,編譯器將無法找到類別定義;另一方面,若確實匯入套件或類別,任何嘗試定義與匯入名稱造成衝突的名稱都將產生錯誤。
建立套件時,該套件中所有成員的預設存取指定字是 internal,也就是說,根據預設,只有該套件的其它成員才看得見套件成員。若要讓類別供套件外的程式碼使用,必須將類別宣告為 public。例如,下列套件包含 SampleCode 和 CodeFormatter 兩個類別:
// SampleCode.as 檔
package samples
{
public class SampleCode {}
}
// CodeFormatter.as 檔
package samples
{
class CodeFormatter {}
}
SampleCode 類別可以在套件外看見,因為它是宣告為 public 類別;但是 CodeFormatter 類別則只能在 samples 套件本身之中才能看見。若嘗試在 samples 套件外存取 CodeFormatter 類別,將產生錯誤,如下列範例所示:
import samples.SampleCode; import samples.CodeFormatter; var mySample:SampleCode = new SampleCode(); // 沒問題,為公用類別 var myFormatter:CodeFormatter = new CodeFormatter(); // 錯誤
若要讓兩個類別都能供套件外的程式碼使用,必須將這兩個類別都宣告為 public。您不能將 public 特質套用至套件宣告。
若要解決使用套件時可能會發生的名稱衝突,完整名稱就很有用。若匯入兩個用相同識別名稱定義類別的套件,就可能會發生這種情況。例如,請考慮下列套件,它也包含名為 SampleCode 的類別:
package langref.samples
{
public class SampleCode {}
}
若如下所示匯入這兩個類別,在參考 SampleCode 類別時就會有名稱衝突:
import samples.SampleCode; import langref.samples.SampleCode; var mySample:SampleCode = new SampleCode(); // 名稱衝突
編譯器無法得知要使用哪一個 SampleCode 類別。若要解決這項衝突,必須使用各個類別的完整名稱,如下所示:
var sample1:samples.SampleCode = new samples.SampleCode(); var sample2:langref.samples.SampleCode = new langref.samples.SampleCode();
|
注意 |
|
具有 C++ 背景的程式設計人員經常將 |
Flash CS3
目前頁面: http://livedocs.adobe.com/flash/9.0_tw/main/00000041.html