官术网_书友最值得收藏!

3.1 類與對象

第2章介紹了基本數據類型的使用,這些類型可以處理整數、浮點數、字符和布爾類型的數據。而類(class)則是一種更加復雜的數據類型,它主要包括兩種成員,即字段(field)和方法(method)。其中,字段用來存儲數據,方法則定義數據的一系列操作。

在Java中,定義類需要使用class關鍵字。下面通過項目資源管理器中的“源包”右鍵菜單“新建”→“Java類”項添加一個新的類,如圖3-1所示。

本例中,將新建的類命名為CAuto。然后,修改CAuto.java文件的內容,如下所示。

圖3-1 添加Java類

代碼中,CAuto類定義了兩個字段和一個方法,分別是:

□ model字段,表示車的型號,定義為String類型,默認為空字符串。

□ doors字段,表示車門數量,定義為int類型,默認為4。

□ moveTo()方法,用于顯示車的移動信息。

String是什么?它也是一個類,這里暫時當作簡單的字符串類型使用就可以了。字符串又是什么?可以把它視為文本內容,還要使用一對雙引號定義。

代碼中使用了String.format()方法,它的功能是將各種類型的數據組合為字符串形式,先照樣子敲代碼就可以了,第6章會詳細討論字符串的應用。

回到CAuto類,應該如何使用它呢?首先,CAuto是一個類型,可以定義此類型的“變量”,也就是CAuto類的實例(instance)。下面的代碼定義了CAuto類型的變量auto。

    CAuto auto;

這里,auto稱為CAuto類的一個實例,或者CAuto類型的對象,可以簡稱為auto對象。不過,auto對象暫時還不能使用,因為它還沒有實例化,其值默認為null。

實例化一個對象時,需要使用new關鍵字,如下面的代碼所示。

    CAuto auto = new CAuto();

接下來,就可以使用auto對象了,如下面的代碼所示。

    public static void main(String[] args) {
    CAuto auto = new CAuto();
    auto.model = "X9";
    auto.moveTo(10, 99);
    }

代碼中,通過圓點運算符(.)調用對象的字段和方法,首先將model字段的值設置為X9,然后調用moveTo()方法。執行代碼,可以看到如圖3-2所示的結果。

此外,注意,main()是程序的入口方法,它定義在應用的主類中。

圖3-2 使用CAuto類的實例

3.1.1 構造函數與對象釋放

再看一下auto對象的實例化代碼。

    CAuto auto = new CAuto();

代碼中的CAuto()是方法嗎?好像是,不過,這可不是一般的方法,而是在調用CAuto類的構造函數,但并沒有定義這個構造函數。

實際上,如果沒有在類中沒有定義構造函數,則會包含一個空的構造函數。當然,也可以自己創建構造函數。下面的代碼在CAuto類中添加一個構造函數。

構造函數雖然看上去和方法差不多,但它的名稱與類名相同,而且不需要定義返回值類型,如moveTo()方法中關于void關鍵字的部分。關于返回值的更多內容,3.2節會詳細討論。

實際開發中,一個類還可以有多個構造函數,只要它們的參數設置能夠有效區分就可以。下面的代碼在CAuto類中創建三個構造函數。

細心的讀者可能會發現一些小問題,例如,這三個構造函數之間并沒有什么聯系,而且在兩個構造函數中出現了重復的代碼。這也許不是什么大問題,但還有機會改進代碼。下面的代碼就是CAuto.java文件修改后的全部代碼。

第一個構造函數中使用了兩個參數,分別指定model和doors字段的值。重點在接下來的兩個構造函數中,首先看下面的版本。

    public CAuto(String m){
    this(m, 4);
    }

當看到this關鍵字時,應該想到當前實例(對象),而這里就是在調用CAuto(String m, int doors)構造函數,其中將車門數設置為4。最后構造函數就比較好理解了,它調用CAuto(String m)版本的構造函數。

實際上,這三個構造函數組成一個構造函數鏈,通過這種方法可以減少重復代碼,提高代碼維護效率。

下面的代碼分別使用這三個構造函數創建對象。

    public static void main(String[] args) {
        CAuto auto1 = new CAuto();
        CAuto auto2 = new CAuto("X9");
        CAuto auto3 = new CAuto("XX", 2);
        System.out.println(auto3.doors);
    }

圖3-3 調用不同的構造函數

代碼執行結果如圖3-3所示。

通過構造函數,可以進行對象的初始化操作,那么,當對象不再使用時應該怎么做呢?實際上,Java運行環境可以自動回收不再使用的對象,大多情況下并不需要開發者編寫代碼進行處理。不過,當對象中使用了一些外部資源時,就應該保證這些資源能夠正確地關閉,例如,打開文件并進行讀寫操作后,就應該及時關閉文件。

3.1.2 getter()和setter()方法

這里并不是要創建名為getter()和setter()的方法,而是通過這兩種方法控制字段數據的讀取和設置操作。

還以CAuto類為例,看一下doors字段的使用,如下面的代碼所示。

    CAuto auto = new CAuto("X9");
    auto.doors = -2;
    System.out.println(auto.doors);

本例中的車門數量設置為-2,難道是在平行宇宙中?還是回到現實世界中,要控制車門數量的設置操作。

對于這樣的問題,可以使用getter()和setter()方法來解決。首先,將字段設置為私有的(private),這樣就不能在類的外部訪問它。然后,使用setXXX()方法設置字段數據,使用getXXX()方法返回字段數據。

下面的代碼展示在CAuto類中修改doors字段的方式。

代碼中所做的修改包括以下幾個。

□ 將doors字段的public修飾符更改為private,稍后會討論這兩個修飾符的區別。

□ 添加setDoors()方法來設置車門數量,其中,當指定的數據在2到5之間時,就修改doors字段的值,否則使用默認的4門。

□ 添加getDoors()方法來獲取車門數量,其中使用return語句返回doors字段的值即可。

□ 構造函數中,對于車門數量的設置,改用setDoors()方法來實現。

下面的代碼測試與車門數量相關的操作。

    public static void main(String[] args) {
        CAuto auto = new CAuto("X9", 6);
        System.out.println(auto.getDoors());
        auto.setDoors(2);
        System.out.println(auto.getDoors());
    }

圖3-4 使用setter和getter方法

代碼執行結果如圖3-4所示。

示例中,首先使用構造函數設置車門數量為6,可以看到,實際上doors設置為4。當使用setDoors()方法設置車門數量為2時,doors字段的值才會正確設置。

實際應用中,可以通過setter()方法控制數據的正確性,設置的數據有問題時,可以使用一個默認值,如前面的示例中那樣。當然,如果數據無效,也可以拋出一個異常(Exception),讓對象的使用者來處理,第5章會討論異常處理的相關內容。

此外,如果一些數據不需要在類的外部設置,只允許讀取,可以只定義getter()方法。

3.1.3 靜態成員與靜態初始化

前面,在CAuto類中創建的字段和方法,都必須使用CAuto類的實例(對象)來訪問,它們稱為類的實例成員。開發中,使用static關鍵字,還可以將成員定義為靜態成員,靜態成員可以使用類的名稱直接訪問。

下面的代碼(CAutoFactory.java文件)創建了一個汽車工廠類。

在CAutoFactory類中,定義了三個靜態成員,分別如下所示。

□ counter字段,生產計數器,表示工廠生產了多少汽車,它定義為私有的,只能在類的內部自動處理。

□ getCounter()方法,以只讀方式返回生產計數器的值。

□ createSuv()方法,用于創建SUV車型。

下面的代碼測試CAutoFactory類的使用。

    public static void main(String[] args) {
        CAuto suv1 = CAutoFactory.createSuv();
        CAuto suv2 = CAutoFactory.createSuv();
        System.out.println("汽車生產數量為" + CAutoFactory.getCounter());
    }

圖3-5 使用靜態成員

代碼執行結果如圖3-5所示。

示例中,使用CAutoFactory類直接調用createSuv()方法,每一次執行后,counter的值都會加1。所以,當創建兩輛SUV汽車對象后,CAutoFactory.getCounter()方法返回的數據就是2。

如果需要對靜態成員進行初始化,還可以在類中使用static語句定義一個結構來完成,結構中的代碼會在第一次調用靜態成員時執行一次。下面的代碼在CAutoFactory類中添加一個靜態初始化結構。

圖3-6 調用靜態初始化結構

再次執行代碼,可以看到如圖3-6所示的結果。

本例中,雖然代碼中多次調用了CAutoFactory類中的靜態成員,但靜態初始化代碼只會執行一次。

此外,使用汽車工廠生產汽車的方法是否使代碼更加直觀呢?實際上,這里使用了一種比較常用的代碼結構,它的名稱正是“工廠方法”。

主站蜘蛛池模板: 宁晋县| 墨江| 洪江市| 南漳县| 礼泉县| 宁晋县| 赤峰市| 抚州市| 北海市| 东辽县| 乌什县| 东乌珠穆沁旗| 历史| 虞城县| 安阳市| 漯河市| 望奎县| 碌曲县| 屯昌县| 宁阳县| 嘉兴市| 思茅市| 虞城县| 沽源县| 汕头市| 屯留县| 肇庆市| 高碑店市| 云阳县| 玉环县| 万源市| 武乡县| 朝阳区| 荔浦县| 中西区| 连云港市| 察隅县| 汤原县| 宝丰县| 新丰县| 台山市|