面向對象——繼承與組合

一、組合的特色函數

二、繼承帶來最大的壞處this

三、設計父類遵循的規則spa

四、什麼時候使用繼承設計

五、什麼時候使用組合指針

 

一、組合的特色code

    提升代碼複用性,增長has-a關係,加強理解對象

二、繼承帶來最大的壞處blog

    破壞父類的封裝性(每一個類都應該封裝它內部信息和實現細節,而只暴露必要的方法給其餘類使用。但繼承關係中,子類能夠直接訪問父類的屬性(內部信息)和方法,從而形成子類和父類的嚴重耦合)。採用組合方法來實現類重用則能提供更好的封裝性。繼承

三、設計父類遵循的規則get

爲了保證父類良好的封裝性,不會被子類隨意改變,設計父類一般應該遵循如下規則:

① 儘可能隱藏父類的內部數據(private);

② 不要讓子類能夠隨意訪問、修改父類的方法。輔助方法設爲private,須要被外部調用public,不但願子類重寫加上final,若但願重寫可是不但願其餘類自由訪問,設爲protected;

③ 在父類構造器中不調用被子類重寫的方法(不然會引發空指針異常)。

好比:new 父類時調用的是父類本身的方法,而經過子類new一個父類時,在父類構造器中實際上調用的是子類方法。

例1

public class FatherSonTest { public static void main(String[] args) { // TODO Auto-generated method stub
        Father f = new Son(); f.getNum(); } } class Father{ private int num; public Father() { num = getNum(); System.out.println("Father, num="+num); } public int getNum() { System.out.println("this is Father!"); return 4; } } class Son extends Father{ private int num; public Son() { num = getNum(); System.out.println("Son, num="+num); } public int getNum() { System.out.println("this is Son!"); return 5; } }

output:

this is Son!

Father, num=5

this is Son!

Son, num=5

this is Son!

例2:

public class a { public static void main(String[]args){ a c=new b(); //下面這裏打印的是a的成員變量s=AAAA 
 System.out.println(c.s); } public String s="AAAA"; //父類構造函數 
    public a(){ call(); } public void call(){ System.out.println("a class call()="+s); } } class b extends a{ public String s="BBBB"; //子類構造函數 
    public b(){ System.out.println("b class b()="+s); } //重寫父類中的call函數 
    public void call(){ System.out.println("b class call()="+s); } }

output:

b class call()=null

b class b()=BBBB

AAAA

因爲父類第一次調用子類的call方法時,子類尚未初始化非靜態變量以及構造方法(靜態成員被初始化了),所以輸出是null。

注意:經過父類的引用類型變量指向子類類型對象,訪問成員變量時是訪問的父類的成員變量。

(類加載時會爲靜態變量賦初值,執行靜態代碼塊,但不會爲實例變量賦初值,只有構造函數執行時纔會賦值)

若但願某些類不被繼承,能夠用final修飾類,或者將全部構造器設爲private,保證子類沒法調用該類的構造器,從而沒法繼承。

四、什麼時候使用繼承

保證子類是一種特殊的父類,加上如下兩個條件之一:

①   子類須要額外增長屬性,而不單單是屬性值的改變;

②   子類須要增長本身獨有的行爲方式。

五、什麼時候使用組合

若只是出於類複用的目的,並不必定須要使用繼承,徹底能夠使用組合來實現。

一般將新類中嵌入舊的對象修飾爲private

相關文章
相關標籤/搜索