2012年2月17日 星期五

[Programming] 物件導向(2) - 名詞定義

自從在案子裡教了程式開發的教育訓練以後,就不斷在寫程式開發的文.....


有鑑於在物件導向程式設計裡,比起原先的基本程式開發的專有名詞還要再更多一點,而且根據地區性的不同還有不同的翻譯,為了避開這種語意上的混淆,我決定先整理一下物件導向程式設計裡會用到的專有名詞和其意義。

所謂的類別 (class),就是像我們上一篇所提到的Student那樣,可以把它想像成一種自己設計的特殊變數型態。就像標準C語言中的int, char....這種型態的意義是一樣的;也可以把它想像成是一種建構物件的藍圖,程式能夠以這個藍圖,產生出物件和藍圖一模一樣的物件。很多時候類別都會包含一個建構子 (constructor) ,用來定義該類別被實體化後的初始狀態。

物件 (object),就是已經用new和該類別的建構子將類別實體化後產生出來的東東。
上面這張圖是我在做專案的程式開發教材時所畫的圖,版權沒有。
如上述的圖所示,當宣告一個Guy類別,變數名稱為joe的時候,只會先產生一個叫做joe的Guy類別參考,還沒有實體記憶體可以來存資料。等到經過new以後,才會在實體記憶體裡抓一塊空格出來讓程式存東西,然後把joe這個參考指到這塊記憶體裡,這個動作稱為實體化,抓出來這塊記憶體,就稱之為物件(object),或稱之為實踐(instance)
所以,物件是真的有實體的。就像現實生活中,眼睛看到的每個東西都算是物件,而它們都有實體,而不是抽象的概念。

現實生活中的各種物件都有它自己的動作 (operation),或是被使用後產生什麼變化或結果。在物件導向程式設計裡,物件自發性的動作,我們稱之為方法 (method),以C語言的概念來說,也有人稱它為函式 (function)
像上一篇中Student類別裡的SexTransform()就是方法,做法是讓學生女變男或男變女。.....咳嗯,SexTransform(性轉換)嘛....自發性的動作...嗯。
總而言之,像鴨子會飛或是會呱呱叫,或是人會走路會跑步會跳會攻擊等等的,可以對該類別做成一個一個方法來使用,所製造出來的物件就不光只是個裝資料的容器而已,它還會動。不過有一點要注意的是,這些方法,因為是寫在類別裡面,所以是針對物件去做處理的方法,所以在還沒建一個實體之前,這些方法是不能用的。

當然,也是有一種類別或方法它是不用先把實體建構出來就可以呼叫方法的函式。這種東西,我們稱為靜態方法 (static method)。這種方法在一開始被呼叫後,就會把記憶體空一塊空間出來處理方法裡面要做的事,執行完了之後,空出來的記憶體不會被釋放掉,所以裡面的區域變數,狀態都會被存下來,不會不見。
所以,假如你的類別裡有一個靜態方法,然後程式在執行的過程用這個類別宣告了好幾個物件,這好幾個物件,都會共用同一個靜態方法,連方法裡的變數都是共用的。這個部分如果沒有掌握好,在debug的時候會把頭髮抓掉一半都不知道問題出在什麼地方。

有靜態方法,當然也有所謂的靜態類別 (static class),原理上和靜態方法是類似的:就是呼叫完之後記憶體空間不會不見。它和一般類別不一樣的地方在於:它不能被實體化,裡面也不能包含實體方法。其實這種靜態類別,通常被用於定義整個系統都會去使用,或是共用的函式集,像是存取資料表的動作、設計模式中的獨體模式 (Singleton) ...等。

以下程式碼為靜態類別和靜態方法的例子,保證不能使用,但是大致上來說就是如此而已。
static class DB
{
    private static SqlConnection sqlConn;
    private static SqlCommand sqlComm;
    private static SqlTransaction sqlTrans;
    
    public static bool Open(){
        try {
            sqlConn = new SqlConnection("");
            sqlConn.Open();

            sqlComm = new SqlCommand();
            sqlComm.Connection = sqlConn;

            sqlTrans = sqlConn.BeginTransaction();
            sqlComm.Transaction = sqlTrans;

            return true;
        }
        catch{
            return false;
        }
    }

    public static bool Update(string strSQL) {
        try
        {
            sqlComm.CommandText = strSQL;
            sqlComm.ExecuteNonQuery();
            return true;
        }
        catch {
            Close(false);
            return false;
        }
    }

    public static void Close() {
        Close(true);
    }

    private static void Close(bool succeed) {
        if (succeed)
        {
            sqlTrans.Commit();
        }
        else {
            sqlTrans.Rollback();
        }
        sqlConn.Close();
    }
}


ref:
[1] 網站製作學習誌
[2] 程式設計筆記byChris

沒有留言: