is a 代表的是類之間的繼承關系,比如PC機是計算機,工作站也是計算機。PC機和工作站是兩種不同類型的計算機,但都繼承了計算機的共同特性。因此在用 Java語言實現時,應該將PC機和工作站定義成兩種類,均繼承計算機類。
has a 代表的是對象和它的成員的從屬關系。同一種類的對象,通過它們的屬性的不同值來區別。比如一台PC機的操作系統是Windows,另一台PC機的操作系統是Linux。操作系統是PC機的一個成員變量,根據這一成員變量的不同值,可以區分不同的PC機對象。
再比如張三和李四都是人,但他們的名字不一樣,可以以此區分這兩個具體的人。名字應該作為人的成員變量。如果將名字叫“張三”的人和名字叫“李四”的人分別定義成兩個類,均繼承“人”這個類,顯然是不合理的。
is a 的意識是如果A是B,那么B就是A的基類。
比如:等邊三角形是三角形,所以三角形就是等邊三角形的基類。
has a 是如果A中有B,那么,B就是A的組成部分
如果你確定兩件對象之間是is-a的關系,那么此時你應該使用繼承;比如菱形、圓形和方形都是形狀的一種,那么他們都應該從形狀類繼承而不是聚合。
如果你確定兩件對象之間是has-a的關系,那么此時你應該使用聚合;比如電腦是由顯示器、CPU、硬盤等組成的,那么你應該把顯示器、CPU、硬盤這些類聚合成電腦類,而不是從電腦類繼承。
===============================================================
現在更多的是強調繼承,好像處處都想到繼承,其實,組合更加的靈活,應首先考慮組合。
組合是在一類類中引用另一個類。生成另一個類的實例。而繼承只是繼承了父類的變量和方法。
區別:使用組合可以用到另一個類中私有的變量和方法,而繼承就不可以用到父類的私有的變量和方法了,他們都有各自的好處,要靈活的運用。
聚合關系,當A創建的時候,B不一定創建;當A消亡時,B不一定消亡。
class A{ private B;}
class B{....}
組合關系,當創建一個A對象時,也會創建一個B對象;當A對象消亡時,作為A的屬性的B對象也會消亡。
class A{private b=new B();....}
class B{....}
繼承是“is a", 組合是“like a"
組合關系是:局部類和整體類的關系
包括
從整體類到局部類的分解過程
從局部類到整體類的組合過程
繼承關系:父類和子類的關系
包括
從子類到父類的抽象過程,父類是基礎類,擁有基本的變量和方法。
從父類到子類的擴展過程
聚合(繼承)代碼如下:
public class Me extends ZhouJieLun
{
public static void main(String[] args){new Me().singing() ;//打印出“我邊吃橄欖邊唱歌”}
}
另外一個辦法,就是組合復用:
public class Me
{
public void singing(){new ZhouJieLun().singing() ;//打印出“我邊吃橄欖邊唱歌”}
}
這樣舉例應該挺清楚了吧
組合與聚合的關系:組合和聚合是有很大區別的,這個區別不是在形式上,而是在本質上:
比如A類中包含B類的一個引用b,當A類的一個對象消亡時,b這個引用所指向的對象也同時消亡(沒有任何一個引用指向它,成了垃圾對象),這種情況叫做組合,反之b所指向的對象還會有另外的引用指向它,這種情況叫聚合。
在實際寫代碼時,組合方式一般會這樣寫:
A類的構造方法里創建B類的對象,也就是說,當A類的一個對象產生時,B類的對象隨之產生,當A類的這個對象消亡時,它所包含的B類的對象也隨之消亡。
聚合方式則是這樣:
A類的對象在創建時不會立即創建B類的對象,而是等待一個外界的對象傳給它,傳給它的這個對象不是A類創建的。
現實生活中:人和手,腳是組合關系,因為當人死亡后人的手也就不復存在了。人和他的電腦是聚合關系