在java以及其餘的面向對象設計模式中,類與類之間主要有6種關係,他們分別是:依賴、關聯、聚合、組合、繼承、實現。他們的耦合度依次加強。java
1. 依賴(Dependence) 編程
依賴關係的定義爲:對於兩個相對獨立的對象,當一個對象負責構造另外一個對象的實例,或者依賴另外一個對象的服務時,這兩個對象之間主要體現爲依賴關係。定義比較晦澀難懂,但在java中的表現仍是比較直觀的:類A當中使用了類B,其中類B是做爲類A的方法參數、方法中的局部變量、或者靜態方法調用。類上面的圖例中:People類依賴於Book類和Food類,Book類和Food類是做爲類中方法的參數形式出如今People類中的。設計模式
代碼樣例:app
[java] view plaincopy編程語言
2.關聯(Association)、、學習
單向關聯:spa
雙向關聯:.net
對於兩個相對獨立的對象,當一個對象的實例與另外一個對象的一些特定實例存在固定的對應關係時,這兩個對象之間爲關聯關係。關聯關係分爲單向關聯和雙向關聯。在java中,單向關聯表現爲:類A當中使用了類B,其中類B是做爲類A的成員變量。雙向關聯表現爲:類A當中使用了類B做爲成員變量;同時類B中也使用了類A做爲成員變量。設計
代碼樣例:面向對象設計模式
[java] view plaincopy
3.聚合(Aggregation)
聚合關係是關聯關係的一種,耦合度強於關聯,他們的代碼表現是相同的,僅僅是在語義上有所區別:關聯關係的對象間是相互獨立的,而聚合關係的對象之間存在着包容關係,他們之間是「總體-個體」的相互關係。
代碼樣例:
[java] view plaincopy
4.組合(Composition)
相比於聚合,組合是一種耦合度更強的關聯關係。存在組合關係的類表示「總體-部分」的關聯關係,「總體」負責「部分」的生命週期,他們之間是共生共死的;而且「部分」單獨存在時沒有任何意義。在下圖的例子中,People與Soul、Body之間是組合關係,當人的生命週期開始時,必須同時有靈魂和肉體;當人的生命週期結束時,靈魂肉體隨之消亡;不管是靈魂仍是肉體,都不能單獨存在,他們必須做爲人的組成部分存在。
[java] view plaincopy
5.繼承(Generalization)
繼承表示類與類(或者接口與接口)之間的父子關係。在java中,用關鍵字extends表示繼承關係。UML圖例中,繼承關係用實線+空心箭頭表示,箭頭指向父類。
6.實現(Implementation)
表示一個類實現一個或多個接口的方法。接口定義好操做的集合,由實現類去完成接口的具體操做。在java中使用implements表示。UML圖例中,實現關係用虛線+空心箭頭表示,箭頭指向接口。
在java中繼承使用extends關鍵字,實現使用implements關鍵字,很直觀。
在學習面向對象設計對象關係時,依賴、關聯、聚合和組合這四種關係之間區別比較容易混淆。特別是後三種,僅僅是在語義上有所區別,所謂語義就是指上下文環境、特定情景等。他們在編程語言中的體現倒是基本相同的,可是基本相同並不等於徹底相同。
下面就來詳細的論述一下在java中如何準確的體現依賴、關聯、聚合和組合。
首先看一看書上對這四種關係的定義:
——摘自《Java面向對象編程》,做者:孫衛琴
以上關係的耦合度依次加強(關於耦合度的概念將在之後具體討論,這裏能夠暫時理解爲當一個類發生變動時,對其餘類形成的影響程度,影響越小則耦合度越弱,影響越大耦合度越強)。由定義咱們已經知道,依賴關係其實是一種比較弱的關聯,聚合是一種比較強的關聯,而組合則是一種更強的關聯,因此籠統的來區分的話,實際上這四種關係、都是關聯關係。
依賴關係比較好區分,它是耦合度最弱的一種,在java中表現爲局域變量、方法的形參,或者對靜態方法的調用,以下面的例子:Driver類依賴於Car類,Driver的三個方法分別演示了依賴關係的三種不一樣形式。
[java] view plaincopy
關聯關係在java中通常使用成員變量來實現,有時也用方法形參的形式實現。依然使用Driver和Car的例子,使用方法參數形式能夠表示依賴關係,也能夠表示關聯關係,畢竟咱們沒法在程序中太準確的表達語義。在本例中,使用成員變量表達這個意思:車是我本身的車,我「擁有」這個車。使用方法參數表達:車不是個人,我只是個司機,別人給我什麼車我就開什麼車,我使用這個車。
[java] view plaincopy
聚合關係是是一種比較強的關聯關係,java中通常使用成員變量形式實現。對象之間存在着總體與部分的關係。例如上例中
[java] view plaincopy
假如給上面代碼賦予以下語義:車是一輛私家車,是司機財產的一部分。則相同的代碼即表示聚合關係了。聚合關係通常使用setter方法給成員變量賦值。
假如賦予以下語義:車是司機的必須有的財產,要想成爲一個司機必需要先有輛車,車要是沒了,司機也不想活了。並且司機要是不幹司機了,這個車就砸了,別人誰也別想用。那就表示組合關係了。通常來講,爲了表示組合關係,經常會使用構造方法來達到初始化的目的,例如上例中,加上一個以Car爲參數的構造方法
[java] view plaincopy
因此,關聯、聚合、組合只能配合語義,結合上下文才可以判斷出來,而只給出一段代碼讓咱們判斷是關聯,聚合,仍是組合關係,則是沒法判斷的。