![]() |
|
Java構(gòu)造器的使用方法 |
|
在Java程序中,每個(gè)類都必須至少有一個(gè)構(gòu)造器(Constructor)。構(gòu)造器是創(chuàng)建一個(gè)類的實(shí)例(對(duì)象)時(shí)需要調(diào)用的一個(gè)特殊的方法。 利用構(gòu)造器可以產(chǎn)生一個(gè)類的實(shí)例,并且提供了一個(gè)地方用來(lái)定義創(chuàng)建類的實(shí)例時(shí)都需要執(zhí)行的初始化(initialize)代碼。構(gòu)造器的定義語(yǔ)法如下: <modifier> <class_name> ( [<argument_list>] ) 從上面的語(yǔ)法中可以看出,它和類中的方法定義很類似:可以有訪問(wèn)修飾符modifier、有自己的方法名稱、有參數(shù)列表、有方法體,因此,可以將構(gòu)造器當(dāng)成一個(gè)特殊的方法(在許多資料里面,就是將Constructor稱為構(gòu)造方法),這個(gè)方法的作用就是用來(lái)產(chǎn)生一個(gè)類的實(shí)例。但是要認(rèn)識(shí)到構(gòu)造器與普通方法的區(qū)別,主要表現(xiàn)在以下3個(gè)方面。 (1)修飾符:和方法一樣,構(gòu)造器可以有任何訪問(wèn)的修飾:public、protected、private或者沒有修飾。不同于方法的是,構(gòu)造器不能有以下非訪問(wèn)性質(zhì)的修飾:abstract、final、native、static或者 synchronized。 (2)返回值:方法能返回任何類型的值或者無(wú)返回值(void),構(gòu)造器沒有返回值,也不需要void。 (3)命名:構(gòu)造器使用和類相同的名字,通常為名詞。而方法則不同,通常為描述一個(gè)操作的動(dòng)詞。按照習(xí)慣,方法通常用小寫字母開始,而構(gòu)造器通常用大寫字母開始。 下面定義一個(gè)用來(lái)表示"美食"的類Food。 源文件:Food.java public class Food { 在Food類中,定義了一個(gè)屬性food_name,還定義了一個(gè)構(gòu)造器,在構(gòu)造器中傳入一個(gè)字符串類型的參數(shù),將參數(shù)值賦給屬性food_name。此時(shí),就可以通過(guò)這個(gè)構(gòu)造器來(lái)實(shí)例化這個(gè)類,如下所示。 Food myDinner = new Food("pizza"); 這樣,就得到了一個(gè)food_name名為"pizza"的實(shí)例,還可以再創(chuàng)建一個(gè)food_name名為"cola"的實(shí)例來(lái)搭配你的晚餐。 如果在程序中沒有定義任何的構(gòu)造器,則編譯器將會(huì)自動(dòng)加上一個(gè)不帶任何參數(shù)的構(gòu)造器。默認(rèn)的構(gòu)造器不帶任何的參數(shù),也沒有"方法體"。 通過(guò)上面的示例,在Food類中定義了一個(gè)帶一個(gè)參數(shù)的構(gòu)造器。如果上面的Food類沒有定義構(gòu)造器,則編譯器會(huì)自動(dòng)加上一個(gè)構(gòu)造器: public class Food { 所以,這時(shí)可以用下面的語(yǔ)句來(lái)實(shí)例化這個(gè)類: Food myDinner = new Food(); 如果在程序中定義了構(gòu)造器,則編譯器將不再提供默認(rèn)的構(gòu)造器,即使定義的構(gòu)造器同樣沒有參數(shù)。如果再使用默認(rèn)構(gòu)造器的話,編譯器會(huì)報(bào)錯(cuò)。 使用Java 構(gòu)造器中的一些注意事項(xiàng): 1.首先要注意的是Java的構(gòu)造器并不是函數(shù),所以他并不能被繼承,這在我們extends的時(shí)候?qū)懽宇惖臉?gòu)造器時(shí)比較的常見,即使子類構(gòu)造器參數(shù)和父類的完全一樣,我們也要寫super就是因?yàn)檫@個(gè)原因。 2.構(gòu)造器的修飾符比較的有限,僅僅只有public private protected這三個(gè),其他的例如任何修飾符都不能對(duì)其使用,也就是說(shuō)構(gòu)造器不允許被成名成抽象、同步、靜態(tài)等等訪問(wèn)限制以外的形式。 3.因?yàn)闃?gòu)造器不是函數(shù),所以它是沒有返回值的,也不允許有返回值。但是這里要說(shuō)明一下,構(gòu)造器中允許存在return語(yǔ)句,但是return什么都不返回,如果你指定了返回值,雖然編譯器不會(huì)報(bào)出任何錯(cuò)誤,但是JVM會(huì)認(rèn)為他是一個(gè)與構(gòu)造器同名的函數(shù)罷了,這樣就會(huì)出現(xiàn)一些莫名其妙的無(wú)法找到構(gòu)造器的錯(cuò)誤,這里是要加倍注意的。 4.構(gòu)造器中一定不要?jiǎng)?chuàng)建自身的實(shí)例,否則會(huì)造成調(diào)用棧溢出錯(cuò)誤。這個(gè)規(guī)則也適用于對(duì)象的實(shí)例變量,如果對(duì)象中有自身的引用,這個(gè)引用一定不能在定義中或者構(gòu)造器中初始化。 5.如果父類是一個(gè)抽象類,那通過(guò)調(diào)用父類的構(gòu)造器,也可以將它初始化,并且初始化其中的數(shù)據(jù)。 6.如果你要在構(gòu)造器中調(diào)用一個(gè)方法時(shí),將該方法聲明為private。 對(duì)于這個(gè)規(guī)則是需要一些說(shuō)明的,假使你的父類構(gòu)造器中要調(diào)用一個(gè)非靜態(tài)方法,而這個(gè)方法不是private的又被子類所重載,這樣在實(shí)際創(chuàng)建子類的過(guò)程中遞歸調(diào)用到了父類的構(gòu)造器時(shí),父類構(gòu)造器對(duì)這個(gè)方法的調(diào)用就會(huì)由于多態(tài)而實(shí)際上調(diào)用了子類的方法,當(dāng)這個(gè)子類方法需要用到子類中實(shí)例變量的時(shí)候,就會(huì)由于變量沒有初始化而出現(xiàn)異常(至于為什么子類中的實(shí)例變量沒有初始化可以參考上邊的實(shí)例初始化過(guò)程),這是Java不想看到的情況。而當(dāng)父類構(gòu)造器中調(diào)用的方法是一個(gè)private方法時(shí),多態(tài)就不會(huì)出現(xiàn),也就不會(huì)出現(xiàn)父類構(gòu)造器調(diào)用子類方法的情況,這樣可以保證父類始終調(diào)用自己的方法,即使這個(gè)方法中調(diào)用了父類中的實(shí)例變量也不會(huì)出現(xiàn)變量未初始化的情況(變量初始化總是在當(dāng)前類構(gòu)造器主體執(zhí)行之前進(jìn)行) 熱點(diǎn)鏈接:
1、Java驅(qū)動(dòng)在智能嵌入式設(shè)備上更具優(yōu)勢(shì) |