第三章我們談到了女媧造人的故事,并且知道了女媧第一天造的其實是雞而不是人。那么女媧是如何造雞的呢?首先她要想象雞究竟是長什么樣子的,然后抓一把泥土并將其做成雞的模樣,然后吹一口氣使其變成一只活生生的雞,接著把它放進大地使其自由行走。考慮到雞有雌雄,并且她造雞居然要耗費一天的時間,所以我們可以推斷,當時女媧應(yīng)該是造了一群雞,可能有成百上千只。雖然這些活雞可能有外觀上的差異,不過,它們都是參照第一只雞的模樣做出來的,所以它們才成為了同一類物種。而在Java世界,萬事萬物皆為“類”,你們這些程序猿(女媧們)通過編寫類代碼(相當于雞的模板),然后就可以用這套模板創(chuàng)建成百上千個對象。下面,我們就看一下如何用上一章的那個Clock類來創(chuàng)建一個對象。
我們先前提到,java程序都是要依賴于虛擬機來運行,而虛擬機要運行程序必須要找到一個入口,這個入口就是main方法,我們可以將這個擁有main方法的類稱為“入口類”。為了不影響原來的Clock類,我們這里新建一個“入口類”,當然,你也可以將這個main方法直接寫在Clock類當中,那樣子的話,Clock類也就同時成為了入口類。
package test.code1;
import java.util.Date;
public class ClockTest{
public static void main(String[] args){
Clock clock = new Clock();
clock.setAlarmTime(new Date());
clock.ring();
}
}
我先來解釋一下main函數(shù)當中的代碼,首先我們創(chuàng)建了一個Clock對象,然后設(shè)置了這個對象的鬧鈴時間(setAlarmTime),并進行了響鈴(ring),運行結(jié)果如下:

我們這里需要重點留意這一句:
Clock clock = new Clock();
先看等號的右邊,我們使用new關(guān)鍵字來創(chuàng)建對象,后面跟的是一個“構(gòu)造器”或者稱為“構(gòu)造方法”。那什么是構(gòu)造方法呢?直接看例子:
public class Clock implements Alarm{
private String brand; //品牌
public Clock(){ }
public Clock(String brand){
this.brand = brand;
}
//...
public void setAlarmTime(Date time){
this.alarmTime=time;
System.out.println("鬧鈴時間:"+time);
}
}
這個類當中,我們看到了兩個名稱都為Clock的方法,根據(jù)前面的知識,由于這兩個方法的參數(shù)不同,所以這兩個方法是“重載”的方法。需要留意的是,跟普通的方法不同(對比一下setAlarmTime方法),這兩個方法的名稱跟類名一模一樣,并且沒有返回值(也沒有void),這兩個方法就是“構(gòu)造方法”。其中,第一個是默認的構(gòu)造方法,這個方法沒有任何參數(shù),方法體也沒有任何內(nèi)容,而第二個構(gòu)造方法則帶一個String類型的參數(shù)。我們可以通過以下兩種方式來創(chuàng)建對象:
Clock clock1 = new Clock(); //使用默認構(gòu)造方法來創(chuàng)建對象
Clock clock2 = new Clock("歐米伽"); //使用自定義構(gòu)造方法來創(chuàng)建對象,這個鐘一誕生就具有了歐米伽的品牌。
需要注意的是,對于默認的構(gòu)造方法,如果我們沒有在這個類當中自定義帶參數(shù)的構(gòu)造方法,那么是可以不寫的。但如果我們自定義了帶參數(shù)的構(gòu)造方法,同時我們又想保留這個默認的構(gòu)造方法,那么我們必須要在類的代碼當中明確寫出默認的這個構(gòu)造方法(就好像上面的Clock類一樣),否則,我是會直接拋棄那個默認的構(gòu)造方法的,編譯后的字節(jié)碼當中也不會有這個方法,所以你將無法繼續(xù)使用,因為Java會認為,你既然有了更精確的構(gòu)造方法,默認的構(gòu)造方法也就不再需要了。
我們再看回這一行代碼:
Clock clock = new Clock();
看完等候右邊的,我們再來看等號左邊的。左邊是一個類名Clock,告知了我們這個對象是一個什么類型的對象,然后跟著一個變量名clock,你可以大致將它理解為這個對象的名字。由于對象是在內(nèi)存當中的,我們看不到摸不著,所以要通過這個名字clock才能調(diào)用對象的屬性以及方法,當然,也只能在權(quán)限范圍之內(nèi)調(diào)用(可以回顧第三章)。創(chuàng)建了對象之后,我們就可以用“對象名.方法名”的方式來調(diào)用對象的方法,或者用“對象名.屬性值”來修改對象的屬性值。
這里,我們還要留意一下“this”這個關(guān)鍵字,它的意思是“這個對象本身”的意思。this跟我們的clock變量名其實是兩個不同的東西,前者是指對象本身(唯一的),而后者只是這個對象的名字,我們也可以用另一個名字或者多個名字來指向同一個對象,例如:
Clock c1 = clock;
Clock c2=c1;
c1、c2、clock都指向同一個對象。就如同“周杰倫”這個對象,除了姓名之外,還有人叫他“周董”,實際上都是指同一個人。既然c1、c2、clock指向同一個對象,那么我們無論在哪個變量上執(zhí)行相關(guān)的方法時,實際上都會作用于同一個對象,例如,我們執(zhí)行c1.setAlarmTime(),那么就可以改變鬧鈴時間。
最后來看一下這個方法:
public void setAlarmTime(Date time){
this.alarmTime=time;
System.out.println("鬧鈴時間:"+time);
}
這里注意一下this.alarmTime=time;這一句,這句的意思是將對象本身的alarmTime變量修改成setAlarmTime參數(shù)當中的那個time。之所以特別強調(diào)這一句,是因為我們經(jīng)常會看到類似這樣的代碼:
this.time=time;
當我們把alarmTime變量的名稱改成“time”的時候,那么setAlarmTime方法中的代碼就要換成上述的樣子,可能會讓你搞不懂左右兩個time的關(guān)系。你只要記住,this代表的是對象本身,當兩個變量的名稱相同時,我們就需要借助this來告訴Java究竟是要改變哪個對象。而如果兩個變量名稱不同,其實也可以省略this,因為Java有足夠的智慧來區(qū)分清楚。例如,我們的Clock類當中,你完全可以直接寫:
alarmTime=time;
[原創(chuàng)作品,未經(jīng)授權(quán)請勿轉(zhuǎn)載]