2010年6月25日 星期五

Flex_建立類別檔案

第一週的課程除了一些FlexBuilder簡單操作以外,有花一點時間介紹物件導向的觀念,然後徒手建立類別檔案,老師也很清楚的說明了相關的內容,趁記憶猶新的時候趕快把他記下來。

雖然寫程式也有一段時間了,聽到"物件導向"這個名詞也不下百次,但是真的被問到什麼叫做物件導向,倒也沒辦法說出一句什麼話可以讓對方立刻明白的,所以今天一定要來定義一下,順便可以讓兩三年後的自己笑一下,所以物件導向就是:以程式邏輯與技巧來描述可獨立呈現之內容的概念,例:杯子、用戶。

因為Flex是以物件導向為基礎,所以第一課就是了解怎麼樣可以寫出一個具物件導向概念的類別檔,以更清楚的架構開發系統。在建置類別檔案時,主要的主成成分有三個,分別為:建構函數、屬性及方法
說明:
建構函數(建構子):當類別被建立出來時會優先被執行的程式內容。(初始化的函數)
屬性:負責描述物件相關內容。(螢幕的廠牌、學生的姓名等)
方法:提共含有邏輯的執行內容。(新增學生、設定屬性並做檢查等)

依照上面所述,可以先寫出一個簡單的類別,含有一個可輸入參數的建構函式,並且設定了初始值;設定了四個屬性,並設定了第二個初始值;最後有一個取得屬性的方法。

完成上述類別檔以後,會有一個疑問,若是需要讓外部讀取或是設定屬性就必須在屬性定義時給定Public的存取權限,但這樣有些想做到只能讀不能寫的屬性就無法呈現了,又或者在資料讀取時要先做一些加工,在資料寫入時要做一些檢核都變的無法做到。那當然,這些都一定會有配套措施,方法就是也常常聽到的"Getter"與"Setter"的函數撰寫。在撰寫上有幾點要注意的,於Flex當中set與get為特殊關鍵詞,當使用後function的名稱於外部使用時就會像是屬性一樣,所以會有也就是只要以"m1.brand"這種方式讀取,"m1.brand=XX"這種方式寫入。所以如此一來就可以設定要經過修飾的屬性為private存取權限,並為了區分類別屬性及setget方法名稱,習慣性將類別屬性前加一底線"_",所以就可以完成下列的類別檔案。


相關規則:
一、建立Class規則
1.package名稱為相對應的資料夾名稱位置。
2.檔案名稱=class名稱=建構函式名稱。

二、建構函式注意事項
1. 函數名稱必須與類別名稱相同
2. 函數的存取權限不可為private
3. 函數內是不允許retrun任何資料
4. 不可描述回傳的資料型態

三、存取權限
1.internal:只有相同package內才可以使用(Flex特有的存取權限)
2.private:只有自己可以存取
3.protected:只有自己與繼承才可存取
4.public:大家皆可以存取

最後,讓我們的程式更物件導向吧~~~~~
附上第二張圖的程式碼,這樣複製簡單一點。

package products
{
public class Monitor
{
//建構函數(建構子) --- 當此類別被建立出來時負責執行的程式內容
public function Monitor(brand:String, size:int)
{
trace("Monitor出生了...");
//分配或儲存資料屬性
//this指的是類別本身
this.brand = brand;
this.size = size;
this.power = false; //第一個初始值設定的方法
}
//屬性
private var _brand:String;
public var size:int;
public var power:Boolean;
private var creationDate:Date = new Date(); //第二個初始值設定的方法

//方法
public function getDesc():String
{
var desc:String = this.brand + " " + this.size + "in.";
return desc;
}
//setter
public function set brand(brand:String):void
{
//去檢查資料是否是空的,如果是空的,我用"N/A"去表達
if(brand == "") {brand = "N/A"; }
this._brand = brand;
}
//getter
public function get brand():String
{
return "品牌:" + this._brand;
}
}
}

9 則留言:

Phebe 提到...
作者已經移除這則留言。
小一 提到...

哈囉!你好:我想請問,我按照esri的creat wms layer 想建立自己的wms layer,方式是與範例一樣建立一個類別檔案,把範例的package com.esri.ags.samples取代為
package src,然後在mxml檔裡寫上
但是執行後卻顯示could not resolve to a component implementaion。
請問是為什麼呢?

小一 提到...

as檔名為MyWMSLayer, 在mxml寫上esri:Map
src:MyWMSLayer/
/esri:Map

ola的家 提到...

如果範例寫的是com.esri.ags.samples,代表他引用的component位置是在com/esri/ags/samples,你現在要改到src底下,不需要加src,因為底層原本就是src。

我不太了解你的描述,但是could not resolve to a component implementaion應該就是單純他在你指定的位置讀不到檔案。

先確認檔案放置的結構。^^

小一 提到...

謝謝版大的回答,我把packge後面的src去掉,在mxml裡用local呼叫就可以了,謝謝你,因為是第一次寫as檔,所以有點搞不清楚

小一 提到...

板主您好,關於您的這篇類別檔教學,讓我想到一個問題,就是當把程式寫在constroctor之中,如ESRI的create WMS Layer範例public function CityStatesWMSLayer(){},那麼當我想用botton click事件去觸發WMS Layer時,在click裡並無法呼叫constructor的方法,那麼當我想放多個WMS Layer時,是否應該要分好幾個as檔寫,因為如果寫在constructor底下,就無法被呼叫,還是說請問有什麼方法呢?希望版主不吝指教我這個flex新手,謝謝!

ola的家 提到...

建構子是當類別(class)被實體化(new)的時候會去執行的函式,有點像是你要使用這個類別時的一些預備動作。

如果你希望在按下按鈕(button click)的時候,執行某一個事情,應該是要撰寫一個一般的函式;而要多次執行時就重複呼叫這個函式。而不是重新new一個類別檔案。

所以,依照你的問題,你應該先判斷你所需要執行的功能,是否應該在建構子中執行?亦或是一般的函式。

我也是Flex新手啦! XD

小一 提到...

那如果我所需的功能是寫在建構子裡的話,我是否應該要使用addeventlistener增加一個方法,將建構子裡的程式搬到新的方法中,才能被click呼叫?

ola的家 提到...

我想你的問題可以分成兩個部分,第一個是你的第一句話『我所需的功能是寫在建構子裡的話』,第二個是你希望你所寫的程式在使用者按下按鈕的時候(click的時候)被執行。

首先建構子的意義是在類別檔的初始化,所以你應該要先判斷你寫在建構子裡面的程式是否'真的需要'在類別被new起來的時候執行?想像一個狀況,如果使用者多次點擊按鈕,那麼你將會產生多個類別實體,而這樣的結果是你希望產生的嗎?如果是當然沒有問題,如果你並非這樣設計,那麼就應該把這些程式移出你的建構子,在其他的地方執行。

第二個重點是你想要在click事件中執行程式,而在Flex當中有兩個方式可以依事件觸發而執行特定的程式碼,第一種是使用標籤語言,也就是click="ClickHandler(event)";另一種是利用你所提到的addEventListener來新增監聽的事件。(你可以參考Flex_事件的第三項,更好的是去讀一下宋志峰老師的書事件那一個章節)

所以接下來是我猜測,你需要寫出使用者按下按鈕時會執行某件事情,而目前你所撰寫的程式碼在某個類別檔的建構子中,所以如果依照目前的架構,你應該在button的click事件中增加一個"ClickHandler(event)",而在ClickHandler(event)去實體化你所撰寫的類別。但這樣會變的有點彆扭,所以去確認你真的需要的程式流程,會比目前該怎麼執行出來要重要。 ^^

張貼留言