復(fù)用類
通過組合或繼承
7.1組合語法
只需將對(duì)象引用置于新類中即可;
初始化類成員引用的方式:
1、在定義對(duì)象的地方。
2、在類的構(gòu)造器中。
3、在正要使用這些對(duì)象之前,這種方式稱為惰性初始化。
4、實(shí)例初始化
示例:
public class Demo{
String s1="Happy";
String s2,s3,s4;
public Demo(){s2="Happy";}
{s4="Happy";}
public String toString(){
if(s3==null){s3="Happy";}
return "s1= " + s1 + "\n" + "s2= " + s2 + "\n" + "s3= " + s3 + "\n" + "s4= " + s4 + "\n";
}
}
7.2繼承語法
使用extends關(guān)鍵字;
為了繼承,一般的規(guī)則是將所有數(shù)據(jù)成員都指定為private,將所有的方法指定為public(protected略);
Java用super關(guān)鍵字表示超類的意思;
繼承復(fù)制了基類的接口;
Java會(huì)自動(dòng)在導(dǎo)出類的構(gòu)造器中插入對(duì)基類構(gòu)造器的調(diào)用;(構(gòu)建過程是從基類“向外”擴(kuò)展的,所以基類在導(dǎo)出類構(gòu)造器可以訪問它之前,就已經(jīng)完成了初始化);如果沒有默認(rèn)的基類構(gòu)造器,或者想調(diào)用一個(gè)帶參的基類構(gòu)造器,就必須用super語句;
7.3代理
繼承與組合的中庸之道:我們將一個(gè)成員對(duì)象置于所要構(gòu)造的類中,與此同時(shí)我們?cè)谛骂愔斜┞读嗽摮蓡T對(duì)象的所有方法。
7.4結(jié)合使用組合和繼承
如果Java的基類擁有某個(gè)已經(jīng)多次重載的方法名稱,那么在導(dǎo)出類中重新定義該方法名稱并不會(huì)屏蔽其在基類中的任何版本。因此無論是在該層或者它的基類中對(duì)方法進(jìn)行定義,重載機(jī)制都可以正常工作。
7.5在組合與繼承之間選擇
組合技術(shù)通常用于想在新類中使用現(xiàn)有類的功能而非它的接口這種情形。即,在新類中嵌入某個(gè)對(duì)象,讓其實(shí)現(xiàn)所需的功能,但新類的用戶看到的只是為新類所定義的接口,而非所嵌入對(duì)象的接口;
繼承用于,使用某個(gè)現(xiàn)有類,并開發(fā)一個(gè)它的特殊版本。通常,這意味著你在使用一個(gè)通用類,并為了某種特殊需要而將其特殊化。
is-a VS has-a
7.6protected關(guān)鍵字
將某些事物盡可能對(duì)這個(gè)世界隱藏起來,但仍然允許導(dǎo)出類的成員訪問它們。
protected也提供了包訪問權(quán)限;
7.7向上轉(zhuǎn)型
“為新的類提供方法”并不是繼承技術(shù)中最重要的方面,其最重要的方面是用來表現(xiàn)新類和基類之間的關(guān)系。這種關(guān)系可以用“新類是現(xiàn)有類的一種類型”這句話加以概括。
在方法參數(shù)為基類引用時(shí),程序代碼可以對(duì)基類和它的所有導(dǎo)出類起作用,這種將導(dǎo)出類引用轉(zhuǎn)換為基類引用的動(dòng)作,我們稱之為向上轉(zhuǎn)型。
對(duì)于組合與繼承,到底是該用組合還是用繼承,一個(gè)最清晰的判斷方法就是問一問自己是否需要從新類向基類進(jìn)行向上轉(zhuǎn)型。如果必須向上轉(zhuǎn)型,則繼承是必要的,否則,應(yīng)當(dāng)好好考慮自己是否需要繼承。
7.8final關(guān)鍵字
final數(shù)據(jù):數(shù)據(jù)恒定不變。對(duì)于基本類型,final使數(shù)值恒定不變,對(duì)于對(duì)象引用,final使引用恒定不變。一旦引用被初始化指向一個(gè)對(duì)象,就無法把它改為指向另一個(gè)對(duì)象。然而,對(duì)象其自身卻是可以修改的。
空白final:聲明為final但又未給定初值的域;編譯器在任何情況下都確??瞻譮inal在使用前必須初始化。必須在域的定義處或者每個(gè)構(gòu)造器中用表達(dá)式對(duì)final進(jìn)行賦值。
final參數(shù):Java允許在參數(shù)列表中以聲明的方式將參數(shù)指明為final。這意味著你無法在方法中更改參數(shù)引用所指向的對(duì)象。
final方法:把方法鎖定,防止任何繼承類修改它的含義。這是出于設(shè)計(jì)的考慮:想要確保在繼承中使方法行為保持不變,并且不會(huì)被覆蓋。
final類:不能繼承該類,也不允許別人這樣做。
有關(guān)final的忠告:將一個(gè)方法指定為final,可能會(huì)妨礙其它程序員在項(xiàng)目中通過繼承來復(fù)用你的類,而這只是因?yàn)槟銢]有想到它會(huì)以那種方式被運(yùn)用。
7.9初始化及類的加載
示例:編譯器加載類A、注意到它有一個(gè)基類B,于是繼續(xù)進(jìn)行加載。接下來,基類的static初始化即會(huì)被執(zhí)行,然后是導(dǎo)出類的static初始化。(因?yàn)閷?dǎo)出類的static初始化會(huì)依賴于基類成員能否被正確初始化)。至此類加載完畢,對(duì)象就可以創(chuàng)建了,首先對(duì)象中的基本類型都會(huì)設(shè)置為默認(rèn)值,對(duì)象引用設(shè)置為null,然后基類的構(gòu)造器會(huì)被調(diào)用。
附:
父類靜態(tài)域——>子類靜態(tài)域——>父類成員初始化——>父類構(gòu)造塊——>父類構(gòu)造方法——>子類成員初始化——>子類構(gòu)造塊——>子類構(gòu)造方法