欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

關(guān)于Java類的構(gòu)造方法詳解

 更新時(shí)間:2023年01月24日 11:48:29   作者:穆哥學(xué)堂  
這篇文章主要介紹了關(guān)于Java類的構(gòu)造方法詳解的相關(guān)資料,需要的朋友可以參考下

?Java語(yǔ)言中,類的構(gòu)造方法是一種很特殊的方法。關(guān)于構(gòu)造方法要記憶和理解的知識(shí)點(diǎn)其實(shí)挺多的,下面我們就來(lái)詳細(xì)的講講構(gòu)造方法,相信看過(guò)這篇文章之后,你會(huì)對(duì)構(gòu)造方法有一個(gè)比較深刻的認(rèn)識(shí)和理解。(預(yù)警:此文較長(zhǎng),請(qǐng)耐心看完!)

首先來(lái)說(shuō)說(shuō)構(gòu)造方法的五個(gè)特點(diǎn):?

一、構(gòu)造方法的名稱必須與類的名稱相同。比如類的名稱叫A,那么它的構(gòu)造方法必須也叫A。?

二、構(gòu)造方法的前面不能聲明返回值類型,即便是void也不行。只有滿足了這兩個(gè)條件,編譯器才會(huì)認(rèn)定這個(gè)方法是構(gòu)造方法。?

三、如果程序員沒(méi)有在類中定義構(gòu)造方法,那么在編譯階段,編譯器會(huì)“免費(fèi)贈(zèng)送”給這個(gè)類一個(gè)構(gòu)造方法,也就是說(shuō),編譯器會(huì)在編譯階段在字節(jié)碼文件中補(bǔ)充添加一個(gè)構(gòu)造方法。但如果程序員已經(jīng)在類中已經(jīng)定義了自己的構(gòu)造方法,則編譯器不會(huì)再為類添加構(gòu)造方法。?

四、編譯器為類“免費(fèi)贈(zèng)送”的這個(gè)構(gòu)造方法是一個(gè)沒(méi)有參數(shù)的構(gòu)造方法。至于說(shuō)這個(gè)構(gòu)造方法里面有什么內(nèi)容,咱們一會(huì)兒再說(shuō)。?

五、編譯器“免費(fèi)贈(zèng)送”的構(gòu)造方法與類的修飾符相同,也就是說(shuō),如果類本身的訪問(wèn)修飾符是public,那么這個(gè)編譯器“免費(fèi)贈(zèng)送”的構(gòu)造方法的前面也會(huì)自動(dòng)加上public關(guān)鍵字,同理,如果類的前面沒(méi)有訪問(wèn)修飾符,那么這個(gè)構(gòu)造方法前面也不會(huì)有任何任何訪問(wèn)修飾符。?

說(shuō)完了構(gòu)造方法的特點(diǎn),我們?cè)賮?lái)說(shuō)說(shuō)構(gòu)造方法的作用。很多教科書上都把構(gòu)造方法的作用說(shuō)成是為了創(chuàng)建一個(gè)對(duì)象,其實(shí)這種理解是有問(wèn)題的。必須承認(rèn),我們創(chuàng)建一個(gè)類的對(duì)象必須要調(diào)用構(gòu)造方法,但構(gòu)造方法的作用其實(shí)并不是為了創(chuàng)建對(duì)象,而是為了“初始化對(duì)象的內(nèi)部狀態(tài)”。“初始化對(duì)象的內(nèi)部狀態(tài)”這句話聽(tīng)起來(lái)不太好理解,其實(shí)就是為了給對(duì)象的各個(gè)屬性賦初始值。我們來(lái)看一個(gè)例子:

Java千問(wèn)25:關(guān)于Java類的構(gòu)造方法,看這一篇就夠了!_子類

我們定義了一個(gè)Person類,并且給Person類定義了兩個(gè)屬性,分別是String類型的name和int類型的age,并且還定義了一個(gè)printInfo()方法,用來(lái)打印這兩個(gè)屬性的值。接下來(lái)我們?cè)趍ain方法中創(chuàng)建兩個(gè)Person類對(duì)象

Java千問(wèn)25:關(guān)于Java類的構(gòu)造方法,看這一篇就夠了!_父類_02

執(zhí)行程序的結(jié)果如下圖:

Java千問(wèn)25:關(guān)于Java類的構(gòu)造方法,看這一篇就夠了!_父類_03

我們發(fā)現(xiàn),這兩個(gè)對(duì)象的name屬性和age屬性的值都是默認(rèn)的那個(gè)初始值,這種初始值其實(shí)沒(méi)有太大意義。如果我們希望在創(chuàng)建對(duì)象的時(shí)候給就對(duì)象的兩個(gè)屬性賦上有意義的值,此時(shí)我們就可以把給屬性賦值的語(yǔ)句寫到構(gòu)造方法當(dāng)中。

Java千問(wèn)25:關(guān)于Java類的構(gòu)造方法,看這一篇就夠了!_子類_04

有了構(gòu)造方法之后,我們?cè)俅螆?zhí)行main方法,得到的結(jié)果是這樣的:

Java千問(wèn)25:關(guān)于Java類的構(gòu)造方法,看這一篇就夠了!_繼承_05

從運(yùn)行結(jié)果上來(lái)看,兩個(gè)對(duì)象的屬性都被賦予了有意義的值。但是問(wèn)題來(lái)了:按照這樣的寫法,我們所創(chuàng)建的每個(gè)Person對(duì)象,name屬性都被賦值為“張三”,而age屬性都被賦值為20。這說(shuō)明我們創(chuàng)建的對(duì)象是“千篇一律”的,并且從情理上也說(shuō)不通,畢竟每個(gè)人都有屬于自己的名字和年齡,不可能每個(gè)人都叫張三年齡20歲。?

那么,如何在創(chuàng)建對(duì)象的時(shí)候,為每個(gè)對(duì)象都初始化屬于自己的真實(shí)數(shù)據(jù)呢?這時(shí)候,我們就要用有參數(shù)的構(gòu)造方法來(lái)搞定這個(gè)問(wèn)題了。我們可以給構(gòu)造方法添加兩個(gè)參數(shù),通過(guò)參數(shù)把數(shù)據(jù)傳遞給對(duì)象的屬性。

Java千問(wèn)25:關(guān)于Java類的構(gòu)造方法,看這一篇就夠了!_子類_06

當(dāng)我們給構(gòu)造方法添加了兩個(gè)參數(shù)之后,卻發(fā)現(xiàn)main方法中原來(lái)本來(lái)正確的代碼出現(xiàn)了語(yǔ)法錯(cuò)誤。

Java千問(wèn)25:關(guān)于Java類的構(gòu)造方法,看這一篇就夠了!_繼承_07

這是為什么呢?就是因?yàn)槲覀兘oPerson類的構(gòu)造方法添加了參數(shù),現(xiàn)在Person類當(dāng)中已經(jīng)沒(méi)有無(wú)參數(shù)的構(gòu)造方法了,既然Person類當(dāng)中已經(jīng)沒(méi)有了無(wú)參數(shù)的構(gòu)造方法,那么我們?cè)趍ain方法中調(diào)用Person類無(wú)參數(shù)的構(gòu)造方法,肯定會(huì)報(bào)錯(cuò)。?

有人會(huì)問(wèn):編譯器不是會(huì)“免費(fèi)贈(zèng)送”給每個(gè)類一個(gè)無(wú)參數(shù)的構(gòu)造方法嗎?那個(gè)送來(lái)的構(gòu)造方法哪去了?這里需要特別說(shuō)明一下:編譯器“贈(zèng)送”給類無(wú)參數(shù)構(gòu)造方法是有條件的,這個(gè)條件就是:程序員沒(méi)有為類定義構(gòu)造方法。也就是說(shuō):只有程序員沒(méi)有為類添加構(gòu)造方法的情況下,編譯器才會(huì)在編譯的時(shí)候給這個(gè)類去自動(dòng)添加一個(gè)無(wú)參數(shù)的構(gòu)造方法,現(xiàn)在,程序員已經(jīng)給Person類定義了構(gòu)造方法,那么編譯器就不會(huì)再給這個(gè)類添加構(gòu)造方法了。?

好,回歸正題,現(xiàn)在我們想修改這個(gè)語(yǔ)法錯(cuò)誤很簡(jiǎn)單,只要在main方法中給Person類的構(gòu)造方法傳遞適當(dāng)?shù)膮?shù)就可以了。

Java千問(wèn)25:關(guān)于Java類的構(gòu)造方法,看這一篇就夠了!_構(gòu)造方法_08

給構(gòu)造方法傳遞了參數(shù)之后,語(yǔ)法錯(cuò)誤自然消失。再次運(yùn)行程序,會(huì)得到這樣的結(jié)果。

Java千問(wèn)25:關(guān)于Java類的構(gòu)造方法,看這一篇就夠了!_父類_09

大家可以看到,這一次,我們就能夠按照我們的意愿,創(chuàng)建出有自己個(gè)性化的對(duì)象了。通過(guò)這個(gè)例子我們可以看出:構(gòu)造方法的作用是給對(duì)象的各個(gè)屬性賦上合理的初始值,從而使得我們所創(chuàng)建的對(duì)象不再是“千篇一律”,而是“千姿百態(tài)”。?

那么,現(xiàn)在我們可以再來(lái)思考兩個(gè)問(wèn)題:第一個(gè)問(wèn)題:構(gòu)造方法可以像普通方法那樣實(shí)現(xiàn)重載嗎?這是完全沒(méi)有問(wèn)題的,我們可以在一個(gè)類中定義多個(gè)構(gòu)造方法,只要這些構(gòu)造方法參數(shù)不同,就構(gòu)成了重載。第二個(gè)問(wèn)題:在一個(gè)構(gòu)造方法中,可以調(diào)用另外一個(gè)構(gòu)造方法嗎?也沒(méi)有問(wèn)題,但調(diào)用的時(shí)候,需要注意:不能像調(diào)用普通方法那樣,通過(guò)類名去調(diào)用,而是需要用一個(gè)關(guān)鍵字this。但是這種調(diào)用也有兩個(gè)條件:?

  • 一、調(diào)用構(gòu)造構(gòu)造方法的語(yǔ)句必須放在第一行。?
  • 二、兩個(gè)構(gòu)造方法不能形成相互調(diào)用關(guān)系。

為了方便表述,我們把一個(gè)類中的兩個(gè)構(gòu)造方法代稱為X和Y。如果我們?cè)赬中調(diào)用了Y,那么就不能在Y中去調(diào)用X了。否則就會(huì)形成循環(huán)依賴關(guān)系,我們來(lái)看下面的例子。

Java千問(wèn)25:關(guān)于Java類的構(gòu)造方法,看這一篇就夠了!_父類_10

我們?cè)谝粋€(gè)構(gòu)造方法中調(diào)用了另一個(gè)構(gòu)造方法,調(diào)用的時(shí)候,需要用到this關(guān)鍵字,并且把調(diào)用語(yǔ)句寫到第一行,這樣才能順利通過(guò)編譯。?

以上我們講解的都是關(guān)于構(gòu)造方法的基本常識(shí),在這個(gè)講解的過(guò)程中,并沒(méi)有設(shè)計(jì)到類的繼承關(guān)系。如果涉及繼承關(guān)系,構(gòu)造方法在定義和調(diào)用的過(guò)程中也有一些必須了解的知識(shí)點(diǎn)。?

首先必須清楚,如果我們創(chuàng)建的是一個(gè)子類的對(duì)象,那么在創(chuàng)建這個(gè)子類對(duì)象的時(shí)候,虛擬機(jī)會(huì)先調(diào)用父類的構(gòu)造方法,之后才去調(diào)用子類的構(gòu)造方法。這個(gè)順序不能錯(cuò),否則會(huì)出現(xiàn)語(yǔ)法錯(cuò)誤。為了說(shuō)明問(wèn)題:我們先來(lái)給Person類添加一個(gè)無(wú)參數(shù)的構(gòu)造方法,并在構(gòu)造方法中輸出一句”父類的構(gòu)造方法”

Java千問(wèn)25:關(guān)于Java類的構(gòu)造方法,看這一篇就夠了!_繼承_11

之后我們?cè)俣x出一個(gè)Person類的子類Student,并且在子類中也定義一個(gè)無(wú)參數(shù)的構(gòu)造方法,在構(gòu)造方法中輸出一句”子類的構(gòu)造方法“

Java千問(wèn)25:關(guān)于Java類的構(gòu)造方法,看這一篇就夠了!_構(gòu)造方法_12

之后,我們?cè)趍ain方法中創(chuàng)建一個(gè)子類對(duì)象。

Java千問(wèn)25:關(guān)于Java類的構(gòu)造方法,看這一篇就夠了!_Java_13

運(yùn)行main方法,得到結(jié)果如下圖:

Java千問(wèn)25:關(guān)于Java類的構(gòu)造方法,看這一篇就夠了!_父類_14

很多人不明白,在子類的構(gòu)造方法中,只是輸出了“子類的構(gòu)造方法”這樣一句話,控制臺(tái)上為什么同時(shí)還輸出了“父類的構(gòu)造方法”?原因就是我們剛才所說(shuō)的:調(diào)用子類構(gòu)造方法的時(shí)候,會(huì)首先調(diào)用父類的構(gòu)造方法。即使程序員沒(méi)有寫代碼去調(diào)用父類的構(gòu)造方法,編譯器也會(huì)把調(diào)用父類構(gòu)造方法的語(yǔ)句補(bǔ)充添加到代碼中。?

那么,補(bǔ)充添加調(diào)用父類構(gòu)造方法的代碼,是如何實(shí)現(xiàn)的?這里必須先講一下子類調(diào)用父類構(gòu)造方法的語(yǔ)法細(xì)節(jié):?

  • 一、子類調(diào)用父類構(gòu)造方法的時(shí)候,不能通過(guò)構(gòu)造方法本身的名稱來(lái)調(diào)用,必須使用super關(guān)鍵字。?
  • 二、子類在它的普通方法中不能調(diào)用父類的構(gòu)造方法,只能在它自身的構(gòu)造方法中才能調(diào)用。?
  • 三、子類調(diào)用父類構(gòu)造方法的語(yǔ)句,必須寫在自身構(gòu)造方法的第一行。?

這三條語(yǔ)法規(guī)則至關(guān)重要,請(qǐng)牢記。按照這個(gè)語(yǔ)法規(guī)則,編譯器看到程序員沒(méi)有在子類構(gòu)造方法中調(diào)用父類構(gòu)造方法,會(huì)按下圖所示的方式把調(diào)用父類構(gòu)造方法的語(yǔ)句添加到代碼中

Java千問(wèn)25:關(guān)于Java類的構(gòu)造方法,看這一篇就夠了!_子類_15

通過(guò)上圖可以看到,如果程序員沒(méi)有在子類構(gòu)造方法中添加調(diào)用父類構(gòu)造方法的語(yǔ)句,編譯器會(huì)自動(dòng)把那條調(diào)用語(yǔ)句補(bǔ)充進(jìn)來(lái),并且放到子類構(gòu)造方法的第一行。在文章一開(kāi)始提出了一個(gè)問(wèn)題:編譯器會(huì)在贈(zèng)送給我們的構(gòu)造方法中添加什么內(nèi)容,此時(shí)你應(yīng)該明白了吧?就是因?yàn)樵谧宇惖臉?gòu)造方法中調(diào)用了父類的構(gòu)造方法,所以我們才會(huì)在控制臺(tái)上會(huì)看到兩條輸出語(yǔ)句。?

現(xiàn)在又冒出一個(gè)問(wèn)題:父類如果有好幾個(gè)構(gòu)造方法,編譯器會(huì)自動(dòng)調(diào)用哪一個(gè)呢?這里必須明確:編譯器只會(huì)調(diào)用那個(gè)無(wú)參數(shù)的構(gòu)造方法,不會(huì)調(diào)用有參數(shù)的構(gòu)造方法。這個(gè)規(guī)則又會(huì)引發(fā)一個(gè)新的問(wèn)題,那就是:如果父類中壓根就沒(méi)有無(wú)參數(shù)的構(gòu)造方法,那怎么辦?在這種情況下,編譯器就會(huì)強(qiáng)制子類定義一個(gè)構(gòu)造方法,并且在它的構(gòu)造方法中,通過(guò)手動(dòng)調(diào)用的形式去調(diào)用父類的構(gòu)造方法,如果你不那么干,編譯器就會(huì)使出它的殺手锏:劃紅線!來(lái)看下圖:

Java千問(wèn)25:關(guān)于Java類的構(gòu)造方法,看這一篇就夠了!_父類_16

既然無(wú)論程序員是否愿意,子類在它的構(gòu)造方法當(dāng)中必須要調(diào)用父類的構(gòu)造方法,那么,通常情況下我們應(yīng)該怎樣調(diào)用父類構(gòu)造方法才算合理呢?一般來(lái)講,子類都會(huì)比父類擁有更多的屬性。就本文而言,父類(Person)有2個(gè)屬性,分別是name和age,而子類(Student)有3個(gè)屬性,分別是name、age和num。當(dāng)然,子類的3個(gè)屬性當(dāng)中,有2個(gè)是從父類那里繼承過(guò)來(lái)的。在創(chuàng)建一個(gè)Student對(duì)象的時(shí)候,必須對(duì)這3個(gè)屬性進(jìn)行初始化。所以通常子類的構(gòu)造方法會(huì)定義3個(gè)參數(shù),這3個(gè)參數(shù)分別用來(lái)初始化子類的3個(gè)屬性。既然子類的3個(gè)屬性當(dāng)中,有2個(gè)是繼承于父類的,那么就可以用父類的構(gòu)造方法去初始化那2個(gè)繼承來(lái)的屬性,而剩下的那個(gè)由子類自身所定義的屬性num,可以在子類自身構(gòu)造方法中實(shí)現(xiàn)初始化,看下圖

Java千問(wèn)25:關(guān)于Java類的構(gòu)造方法,看這一篇就夠了!_Java_17

通常來(lái)講,子類就是這樣調(diào)用父類構(gòu)造方法的。?

最后再回答一個(gè)問(wèn)題:普通方法的名稱可以與類名相同嗎?答案是:可以!在這種情況下,編譯器區(qū)分該方法是普通方法還是構(gòu)造方法,就看方法的前面有沒(méi)有聲明返回值類型。這就是為什么Java語(yǔ)言規(guī)定構(gòu)造方法不能有聲明返回值類型的原因。?

希望通過(guò)閱讀本文,能讓你理解構(gòu)造方法的意義和用法!

到此這篇關(guān)于關(guān)于Java類的構(gòu)造方法詳解的文章就介紹到這了,更多相關(guān)Java類的構(gòu)造方法內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論