對ActionScript語言函數重載的理解

ActionScript與JavaScript類似,都是符合ECMAScript語言規範的語言。ActionScript 3.0更是向面向對象語言靠近了一大步。相對而言,JavaScript則在停留在基於對象的層次上(曾經看到一份資料,說Firefox對JavaScript的支持有一個時間表,大概到07年春季就能支持JavaScript2.0,目前也就是1.5左右)。


拋開ActionScript與JavaScript的版本不談,讓我們探討一些以下幾個問題:
1.ActionScript 3.0 是面向對象的嗎?
2.ActionScript 3.0 爲什麼不支持函數重載

首先,官方對ActionScript3.0的描述如下:
ActionScript 3.0 offers a robust programming model that will be familiar to developers with a basic knowledge of object-oriented programming.

Because of ActionScript's roots as a scripting language, ActionScript 3.0 OOP support is optional. This affords programmers flexibility in choosing the best approach for projects of varying scope and complexity. For small tasks, you may find that using ActionScript with a procedural programming paradigm is all you need. For larger projects, applying OOP principles can make your code easier to understand, maintain, and extend.

從上述敘述來看,ActionScript的確是支持面嚮對象語言的,但它不是作爲一個面嚮對象語言來設計的。它源自腳本語言,並支持對象的概念。引入面向對象機制是爲了克服腳本語言面對大型軟件開發的重用、維護及擴展的難題。實際上,脫離應用和歷史,談論某種語言的面向對象機制的純粹性毫無意義可言(就像論壇經常就C++或Java孰優孰劣論戰一樣毫無意義)。

其次,ActionScript語言爲什麼不支持函數重載。

照我的理解,函數重載(Function Override)從來不是面嚮對象語言的核心。因此,ActionScript語言是否支持函數重載不應該成爲人們批評或質疑它的原因之一,是否實現函數重載完全取決於你的應用。

曾經遇到一個問題,Java語言的某個類接口要映射要ActionScript類,由於該類的接口有函數重載的現象,導致ActionScript無法聲明相應的接口。例如:
//Java類
interface PetStoreFacade{
Account getAccount(String username);
Account getAccount(String username, String password);
//...
}

//ActionScript類
interface PetStoreFacade{
function getAccount(username:String):Account;
function getAccount(username:String, password:String):Account;//ERROR,ActionScript不支持
}

從此例,大家可以看出,討論ActionScript是否支持函數重載的來源了(這大概是其中之一,即與支持函數重載的語言配合工作,或者要從支持函數重載的語言遷移到ActionScript就可能會遇到函數重載的問題)。

關於ActionScript支持函數重載的文章很多,通過ActionScript提供的語言機制和變通的手法,可以讓ActionScript支持函數重載。示例如下:

class PetStoreFacadeImpl{
function getAccount(obj:*):Account{
if(arguments.length==1){
if(arguments[0] typeof 'String'){
//do getAccount(username:String)
}
}
else if(arguments.length==2){
if(arguments[0] typeof 'String' && arguments[1] typeof 'String'){
//do getAccount(username:String,password:String)
}
}
}
}

通過arguments的判斷比較,實現了函數重載,只需調用時傳入合適的參數即可。不過我們仍然要問,爲什麼ActionScript不能直接支持函數重載。語言內部的實現機制是怎麼樣的?仔細查閱了一些資料之後,發現這個問題其實很簡單。原來,這跟ActionScript語言的內部設計實現有關。我們給出幾個重要的概念,有助於理解上述問題。

(一)函數也是對象
ActionScript語言所謂的函數實際上也是對象(即Function),而且函數也是對象。函數可以依附於任何對象,它是自由的。而面嚮對象語言例如Java,函數是和類實例綁定在一起的(靜態函數可以脫離類實例,但綁定於類,仍然不能自由訪問)。

(二)對象是關聯數組
ActionScript語言的所謂對象,實際上是一個屬性和函數關聯數組。你可以定義一個類,包含若干屬性和函數。例如上述PetStoreFacadeImpl類。假設它包含一個String類型的屬性attribute,可以通過.操作符訪問屬性,如:
PetStoreFacade facade = new PetStoreFacadeImpl();
var attr:String = facade.attribute;

訪問函數,通過 facade.getAccount(username)調用函數。實際上,還可以這樣:
var attr:String = facade['attribute'];//數組
facade['getAccount'].call(null,username) //數組
或者
facade['getAccount'].call(null,username,password) //數組

看來,屬性和函數標識是作爲其對象訪問時的唯一主鍵,因此也就沒辦法直接支持編碼式的函數重載了

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章