|  | |
| Java構造器的使用方法 | |
| 在Java程序(xu)中,每個(ge)(ge)類(lei)都必須(xu)至少有一個(ge)(ge)構造(zao)器(Constructor)。構造(zao)器是創建(jian)一個(ge)(ge)類(lei)的(de)實(shi)例(對象(xiang))時需要調用的(de)一個(ge)(ge)特(te)殊的(de)方法。 利用構(gou)造器可以產生一個類的實例,并(bing)且提供了一個地方用來定義創建類的實例時都需(xu)要執行的初始化(initialize)代(dai)碼(ma)。構(gou)造器的定義語(yu)法如(ru)下:     <modifier>  <class_name>  ( [<argument_list>] ) 從上面的(de)(de)(de)語(yu)法中(zhong)可(ke)以(yi)(yi)看出(chu),它和(he)類中(zhong)的(de)(de)(de)方(fang)(fang)法定義很類似:可(ke)以(yi)(yi)有訪(fang)問修(xiu)飾符modifier、有自己(ji)的(de)(de)(de)方(fang)(fang)法名稱、有參(can)數列表(biao)、有方(fang)(fang)法體,因(yin)此,可(ke)以(yi)(yi)將(jiang)構造(zao)器(qi)當成一個(ge)(ge)特殊的(de)(de)(de)方(fang)(fang)法(在許多(duo)資(zi)料里(li)面,就是將(jiang)Constructor稱為(wei)構造(zao)方(fang)(fang)法),這個(ge)(ge)方(fang)(fang)法的(de)(de)(de)作用就是用來產生一個(ge)(ge)類的(de)(de)(de)實例(li)。但(dan)是要認識到構造(zao)器(qi)與普通方(fang)(fang)法的(de)(de)(de)區別,主要表(biao)現在以(yi)(yi)下3個(ge)(ge)方(fang)(fang)面。 (1)修(xiu)飾(shi)符:和方(fang)法一樣,構造器可以有(you)(you)任何訪問(wen)的修(xiu)飾(shi):public、protected、private或(huo)者沒有(you)(you)修(xiu)飾(shi)。不同于方(fang)法的是,構造器不能有(you)(you)以下非訪問(wen)性(xing)質(zhi)的修(xiu)飾(shi):abstract、final、native、static或(huo)者 synchronized。   (2)返(fan)回(hui)(hui)值(zhi):方法(fa)能返(fan)回(hui)(hui)任何類型的值(zhi)或者無返(fan)回(hui)(hui)值(zhi)(void),構(gou)造器沒有(you)返(fan)回(hui)(hui)值(zhi),也(ye)不需(xu)要void。 (3)命名(ming)(ming):構造(zao)器使用和類相同的名(ming)(ming)字(zi),通(tong)常(chang)(chang)為名(ming)(ming)詞。而(er)(er)方(fang)法則不同,通(tong)常(chang)(chang)為描述(shu)一個操作的動(dong)詞。按照習慣,方(fang)法通(tong)常(chang)(chang)用小寫(xie)字(zi)母(mu)開始(shi),而(er)(er)構造(zao)器通(tong)常(chang)(chang)用大寫(xie)字(zi)母(mu)開始(shi)。 下面定義一(yi)個用來表示"美(mei)食"的類Food。 源文件(jian):Food.java     public class Food { 在Food類中,定義(yi)了(le)(le)一個(ge)屬性food_name,還定義(yi)了(le)(le)一個(ge)構(gou)(gou)(gou)造(zao)(zao)器,在構(gou)(gou)(gou)造(zao)(zao)器中傳入一個(ge)字符串類型的(de)參數,將參數值(zhi)賦給屬性food_name。此時(shi),就可以(yi)通過(guo)這個(ge)構(gou)(gou)(gou)造(zao)(zao)器來實例(li)化(hua)這個(ge)類,如(ru)下所示。   Food myDinner = new Food("pizza");   這樣,就(jiu)得(de)到了一個food_name名為"pizza"的(de)(de)實例,還可(ke)以再創建一個food_name名為"cola"的(de)(de)實例來搭配你的(de)(de)晚餐。 如(ru)果在程序(xu)中沒有定義(yi)任何的(de)(de)構造器(qi)(qi),則編譯器(qi)(qi)將會(hui)自動加上一個不(bu)帶任何參數的(de)(de)構造器(qi)(qi)。默認的(de)(de)構造器(qi)(qi)不(bu)帶任何的(de)(de)參數,也(ye)沒有"方法體"。 通過上(shang)(shang)面(mian)(mian)的(de)示(shi)例,在Food類(lei)中定義了一(yi)(yi)個(ge)(ge)帶一(yi)(yi)個(ge)(ge)參數的(de)構造器。如果上(shang)(shang)面(mian)(mian)的(de)Food類(lei)沒有定義構造器,則編譯器會自動加上(shang)(shang)一(yi)(yi)個(ge)(ge)構造器:     public class Food {    所以,這時(shi)可(ke)以用下面(mian)的語(yu)句來實例(li)化這個類:   Food myDinner = new Food(); 如果在程(cheng)序中定(ding)義了構(gou)(gou)造器,則(ze)編(bian)譯(yi)器將不再(zai)提供默認的(de)構(gou)(gou)造器,即使(shi)定(ding)義的(de)構(gou)(gou)造器同(tong)樣沒有參數(shu)。如果再(zai)使(shi)用默認構(gou)(gou)造器的(de)話,編(bian)譯(yi)器會報錯。 使用Java 構造器中的一些注意事項: 1.首先要(yao)注(zhu)意的(de)是Java的(de)構(gou)造(zao)器并不是函數(shu),所以(yi)他并不能被(bei)繼承,這在我們extends的(de)時(shi)候寫子類的(de)構(gou)造(zao)器時(shi)比較(jiao)的(de)常見,即使子類構(gou)造(zao)器參數(shu)和父類的(de)完全一樣,我們也要(yao)寫super就是因為這個(ge)原因。 2.構造器的修飾(shi)符比較的有限(xian),僅(jin)僅(jin)只(zhi)有public private protected這三(san)個,其(qi)他的例如(ru)任何修飾(shi)符都不能對其(qi)使(shi)用,也就是說(shuo)構造器不允許被成(cheng)名成(cheng)抽象(xiang)、同(tong)步、靜態(tai)等等訪問限(xian)制以外(wai)的形式。 3.因為構造(zao)器(qi)(qi)不(bu)(bu)是(shi)(shi)(shi)(shi)函(han)數,所以它是(shi)(shi)(shi)(shi)沒有返(fan)回(hui)值的,也(ye)不(bu)(bu)允許有返(fan)回(hui)值。但是(shi)(shi)(shi)(shi)這(zhe)里要說明一下,構造(zao)器(qi)(qi)中(zhong)允許存(cun)在return語句,但是(shi)(shi)(shi)(shi)return什(shen)么都(dou)不(bu)(bu)返(fan)回(hui),如果你指定了返(fan)回(hui)值,雖然編譯器(qi)(qi)不(bu)(bu)會(hui)報出(chu)任(ren)何(he)錯(cuo)誤,但是(shi)(shi)(shi)(shi)JVM會(hui)認為他是(shi)(shi)(shi)(shi)一個與構造(zao)器(qi)(qi)同名的函(han)數罷了,這(zhe)樣就會(hui)出(chu)現一些莫(mo)名其妙的無法(fa)找到(dao)構造(zao)器(qi)(qi)的錯(cuo)誤,這(zhe)里是(shi)(shi)(shi)(shi)要加倍注(zhu)意的。 4.構造(zao)器中一定不要(yao)創建自身的(de)實例,否則會造(zao)成調用棧溢出錯誤。這個規則也(ye)適(shi)用于對(dui)象的(de)實例變量,如果(guo)對(dui)象中有(you)自身的(de)引(yin)用,這個引(yin)用一定不能在(zai)定義中或(huo)者構造(zao)器中初始化。 5.如果父(fu)類(lei)是(shi)一個抽象(xiang)類(lei),那通過調用父(fu)類(lei)的(de)構造器,也可(ke)以將它初始化(hua),并且初始化(hua)其中的(de)數據。 6.如果你要在構(gou)造器中(zhong)調用一個(ge)方法(fa)(fa)時,將該方法(fa)(fa)聲(sheng)明為private。 對(dui)于這(zhe)(zhe)個規則是(shi)需要一些(xie)說明的(de)(de),假(jia)使(shi)你的(de)(de)父類(lei)(lei)(lei)(lei)構(gou)造(zao)器(qi)(qi)(qi)中要調(diao)(diao)用(yong)一個非靜態方(fang)法(fa)(fa)(fa),而(er)這(zhe)(zhe)個方(fang)法(fa)(fa)(fa)不是(shi)private的(de)(de)又被子(zi)(zi)類(lei)(lei)(lei)(lei)所重載,這(zhe)(zhe)樣(yang)(yang)在實(shi)(shi)(shi)際創建(jian)子(zi)(zi)類(lei)(lei)(lei)(lei)的(de)(de)過程中遞歸調(diao)(diao)用(yong)到(dao)了(le)父類(lei)(lei)(lei)(lei)的(de)(de)構(gou)造(zao)器(qi)(qi)(qi)時(shi),父類(lei)(lei)(lei)(lei)構(gou)造(zao)器(qi)(qi)(qi)對(dui)這(zhe)(zhe)個方(fang)法(fa)(fa)(fa)的(de)(de)調(diao)(diao)用(yong)就(jiu)會(hui)由于多態而(er)實(shi)(shi)(shi)際上(shang)調(diao)(diao)用(yong)了(le)子(zi)(zi)類(lei)(lei)(lei)(lei)的(de)(de)方(fang)法(fa)(fa)(fa),當(dang)(dang)這(zhe)(zhe)個子(zi)(zi)類(lei)(lei)(lei)(lei)方(fang)法(fa)(fa)(fa)需要用(yong)到(dao)子(zi)(zi)類(lei)(lei)(lei)(lei)中實(shi)(shi)(shi)例(li)變(bian)(bian)(bian)(bian)量(liang)(liang)的(de)(de)時(shi)候(hou),就(jiu)會(hui)由于變(bian)(bian)(bian)(bian)量(liang)(liang)沒(mei)有初(chu)始(shi)(shi)化而(er)出(chu)現(xian)異常(至于為(wei)什么子(zi)(zi)類(lei)(lei)(lei)(lei)中的(de)(de)實(shi)(shi)(shi)例(li)變(bian)(bian)(bian)(bian)量(liang)(liang)沒(mei)有初(chu)始(shi)(shi)化可以參考(kao)上(shang)邊的(de)(de)實(shi)(shi)(shi)例(li)初(chu)始(shi)(shi)化過程),這(zhe)(zhe)是(shi)Java不想看到(dao)的(de)(de)情況。而(er)當(dang)(dang)父類(lei)(lei)(lei)(lei)構(gou)造(zao)器(qi)(qi)(qi)中調(diao)(diao)用(yong)的(de)(de)方(fang)法(fa)(fa)(fa)是(shi)一個private方(fang)法(fa)(fa)(fa)時(shi),多態就(jiu)不會(hui)出(chu)現(xian),也就(jiu)不會(hui)出(chu)現(xian)父類(lei)(lei)(lei)(lei)構(gou)造(zao)器(qi)(qi)(qi)調(diao)(diao)用(yong)子(zi)(zi)類(lei)(lei)(lei)(lei)方(fang)法(fa)(fa)(fa)的(de)(de)情況,這(zhe)(zhe)樣(yang)(yang)可以保證父類(lei)(lei)(lei)(lei)始(shi)(shi)終調(diao)(diao)用(yong)自(zi)己的(de)(de)方(fang)法(fa)(fa)(fa),即使(shi)這(zhe)(zhe)個方(fang)法(fa)(fa)(fa)中調(diao)(diao)用(yong)了(le)父類(lei)(lei)(lei)(lei)中的(de)(de)實(shi)(shi)(shi)例(li)變(bian)(bian)(bian)(bian)量(liang)(liang)也不會(hui)出(chu)現(xian)變(bian)(bian)(bian)(bian)量(liang)(liang)未(wei)初(chu)始(shi)(shi)化的(de)(de)情況(變(bian)(bian)(bian)(bian)量(liang)(liang)初(chu)始(shi)(shi)化總(zong)是(shi)在當(dang)(dang)前類(lei)(lei)(lei)(lei)構(gou)造(zao)器(qi)(qi)(qi)主體(ti)執行之前進行) 熱(re)點鏈(lian)接: 
         1、Java驅動在智能嵌入式設備上更具優勢 |