Java筆記--static關(guān)鍵字、繼承
一、static關(guān)鍵字
static關(guān)鍵字:修飾符,可以修飾成員變量,成員方法。
特點(diǎn):
1、被類的所有對象所共享



可以看到第二個(gè)學(xué)生對象的school信息和第一個(gè)共享。
2、多了一種調(diào)用方式,可以通過類名.調(diào)用。

通過對象.調(diào)用和通過類名.調(diào)用都可以,但是通常使用類名進(jìn)行調(diào)用
3、隨著類加載而加載,優(yōu)先于對象而存在。也就是說在new對象之前就可以調(diào)用類名.

這樣是不會報(bào)錯(cuò)的。
在創(chuàng)建工具類的時(shí)候,如果不加static,只能通過創(chuàng)建工具類的對象,然后對象.方法名調(diào)用方法。但是如果在方法中加入static,就可以通過類名.方法名的方式調(diào)用方法,同時(shí)將工具類的構(gòu)造方法private,防止創(chuàng)建工具類對象。
*在靜態(tài)方法中,只能直接訪問靜態(tài)成員變量和靜態(tài)成員方法,要訪問非靜態(tài)的成員變量和成員方法,只能通過創(chuàng)建對象,然后通過對象來調(diào)用非靜態(tài)的成員變量和成員方法。

在這里我們創(chuàng)建了一個(gè)靜態(tài)成員變量,一個(gè)成員變量,一個(gè)靜態(tài)成員方法和一個(gè)成員方法。
當(dāng)我們在main方法中調(diào)用靜態(tài)成員變量num1和靜態(tài)成員方法method( )的時(shí)候沒有報(bào)錯(cuò),但是當(dāng)我們?nèi)フ{(diào)用非靜態(tài)的成員變量num2和非靜態(tài)的成員方法print( )的時(shí)候,報(bào)錯(cuò)了。
想一想內(nèi)存中的過程,因?yàn)閹в衧tatic,隨著類加載而加載,優(yōu)先于對象存在,當(dāng)類加載完成的時(shí)候,帶有static的main方法加載完成。而非靜態(tài)的成員變量和成員方法是當(dāng)創(chuàng)建對象后內(nèi)存中才存在。
*static中不允許使用this關(guān)鍵字。
同上面一樣,因?yàn)閟tatic隨著類的加載而加載,優(yōu)先于對象。
重新認(rèn)識一下main方法:
public :權(quán)限修飾符,因?yàn)閙ain方法是要被JVM調(diào)用的。
static :被JVM調(diào)用,不用創(chuàng)建對象。
因?yàn)閙ain方法是靜態(tài)的,所以測試類中的方法都是靜態(tài)的,因?yàn)闇y試類中不用創(chuàng)建對象。
void:被JVM調(diào)用,不需要返回值。
main:方法名,JVM只認(rèn)識這個(gè)。
String[ ] args :以前是做鍵盤錄入的,現(xiàn)在有了Scanner,現(xiàn)在沒用了。

二、繼承
繼承:讓類與類之間產(chǎn)生關(guān)系 (子父類關(guān)系),子類可以直接使用父類中非私有的成員。



繼承的格式:


如圖所示,Coder類和Manager具有相同的屬性。

這樣之后,Employee類就是Coder類和Manager類的父類,子類就可以調(diào)用父類中的非私有的成員了。

我們可以看到Coder可以正常調(diào)用Employee類中的成員。
現(xiàn)在我們將Employee中的name私有:


此時(shí)發(fā)現(xiàn)已經(jīng)報(bào)錯(cuò)了。其實(shí)對于private的成員變量,我們依然可以通過get和set方法來調(diào)用父類成員變量。


輸出結(jié)果:

由此可見,繼承可以提高代碼的復(fù)用性。
什么時(shí)候使用繼承:

如果在子類出現(xiàn)了同名的成員變量,代碼會遵循就近原則,如果非要使用父類的成員變量,可以使用super.來調(diào)用。

子類和父類中都有成員num,我們創(chuàng)建一個(gè)子類對象調(diào)用num。

運(yùn)行結(jié)果:



方法重寫:


注意事項(xiàng):


Java中繼承的特點(diǎn):
Java只支持單繼承,不支持多繼承,但支持多層繼承
一個(gè)兒子只能有一個(gè)父親,不能有很多父親,但是兒子可以有兒子。
繼承中的構(gòu)造方法:
子類在完成初始化之前,會先完成父類的初始化。不然的話:


在所有的構(gòu)造方法中,都默認(rèn)隱藏了一句話 super( );通過這句代碼,來訪問父類的空參構(gòu)造方法。
這里我們創(chuàng)建一個(gè)子類和父類,分別提供其無參的構(gòu)造方法和帶參的構(gòu)造方法。

然后創(chuàng)建兩個(gè)子類對象:

運(yùn)行程序:

可以看到除了子類的空參和帶參的構(gòu)造方法執(zhí)行了之外,父類的空參構(gòu)造方法也執(zhí)行了兩次。
這就是我們之前提到的,在所有構(gòu)造方法(包括父類)的第一行,隱藏了一句super( );,通過這句代碼,訪問父類的空參構(gòu)造方法。
1、為什么子類調(diào)用構(gòu)造方法的時(shí)候,會先調(diào)用父類的構(gòu)造方法?
因?yàn)槿绻^承父類的屬性,就得完成父類的初始化。
2、子類調(diào)用父類的空參構(gòu)造方法能理解,為什么父類也要隱藏一句super( )?
其實(shí)在Java中,所有的類都直接或間接的繼承Object類,也可以是除了Object類,所有的類的第一行super( )。