在uml圖中 最複雜的也就是泛化,實現,依賴,關聯,這四種關係了,如果弄清了這幾種關係那麼在理解UML圖的時候就會變得輕車熟路了!
如果你對着幾種關係一點都不熟悉的話可以看一下uml中的四種關係,這篇博客簡單的介紹了一下這幾種關係,本文將重點的介紹一下,這幾種關係在代碼裏如何實現的!
一、泛化關係
我想這個也可能是最簡單的關係了,泛化就是特殊到一半的過程,也就是繼承的相反的過程,子類繼承自父類,而父類是從子類泛化而來!
泛化(generalization)關係是一個類(稱爲子類、子接口)繼承另外的一個類(稱爲父類、父接口)的功能,並可以增加它自己的新功能的能力,繼承是類與類或者接口與接口之間最常見的關係;在Java中此類關係通過關鍵字extends明確標識,在c#中用:來表示。在設計時一般沒有爭議性。
<span style="font-size:18px;">namespace DEMO
{
//類繼承類
class ClassB: ClassA { }
//接口繼承接口
interface InterfaceB: InterfaceA { }
}</span>
二、實現關係
實現(realization)關係指的是一個class類實現interface接口(可以是多個)的功能;實現是類與接口之間最常見的關係;在Java中此類關係通過關鍵字implements明確標識,在c#中用“:”表示在設計時一般沒有爭議性;
<span style="font-size:18px;">namespace DEMO
{
//類實現接口
class ClassC:InterfaceC{ }
}</span>
三、依賴關係
依賴(dependency)關係: 也是類與類之間的連接. 表示一個類依賴於另一個類的定義. 依賴關係總是單向的 。可以簡單的理解,就是一個類A使用到了另一個類B,而這種使用關係是具有偶然性的、、臨時性的、非常弱的,但是B類的變化會影響到A;比如某人要過河,需要借用一條船,此時人與船之間的關係就是依賴;表現在代碼層面,爲類B作爲參數被類A在某個method方法中使用。或者在方法體重聲明該類的變量,或者直接引用該類!
public class Boat {
/// <summary>
/// 過河
/// </summary>
public voidriverCrossing(){
//啓動
//過河
}
public staticvoid riverCrossingByShip(){
//用大 船過河
}
}//end Boat
public class Person {
//通過參數的形式用Bote 類
//Bote類被Person類的一個方法所持有,生命週期隨着方法執行結束而結束。
/// <summary>
/// 過河
/// </summary>
/// <paramname="bote">船的實例</param>
public voidriverCrossing(Boat bote){
bote.riverCrossing();
}
//在方法體重生命該類的變量
//注意Bote類的生命週期,當riverCrossing方法被調用的時候,才被實例化。
//持有Bote類的是Person類的一個方法,而不是Person類,這點是最重要的。
public voidriverCrossing() {
Boatbote = new Boat();
bote.riverCrossing();
}
//直接應用該類
public voidriverCrossing() {
Boat.riverCrossingByShip();
}
}//end Person
四、關聯關係
關聯關係是實線加箭頭表示。表示類之間的關係比依賴要強。
例如,水和氣候是關聯的,表示如下:
在代碼中的表現如下:
<span style="font-size:18px;">namespace DEMO
{
/// <summary>
/// 水
/// </summary>
class Water
{
//吧氣候類 的實例作爲該類的一個變量!
public Climateclimate;
publicWater() {
}
}
/// <summary>
/// 氣候
/// </summary>
class Climate
{
publicClimate()
{
}
}
}</span>
可見,在Water類屬性中增加了Climate類。
關聯關係有單向關聯、雙向關聯、自身關聯、多維關聯等等。其中後三個可以不加箭頭。
單向關聯:
雙向關聯:
自身關聯:
多維關聯:
關聯和依賴的區別:
從類的屬性是否增加的角度看:
發生依賴關係的兩個類都不會增加屬性。其中的一個類作爲另一個類的方法的參數或者返回值,或者是某個方法的變量而已。
發生關聯關係的兩個類,其中的一個類成爲另一個類的屬性,而屬性是一種更爲緊密的耦合,更爲長久的持有關係。
從關係的生命週期來看:
依賴關係是僅當類的方法被調用時而產生,伴隨着方法的結束而結束了。
關聯關係是當類實例化的時候即產生,當類銷燬的時候,關係結束。相比依賴講,關聯關係的生存期更長。
關聯關係按關係強弱右分爲聚合 和組合 ,下邊用大雁和雁羣的例子講解一下!
大雁喜歡熱鬧害怕孤獨,所以它們一直過着羣居的生活,這樣就有了雁羣,每一隻大雁都有自己的雁羣,每個雁羣都有好多大雁,大雁與雁羣的這種關係就可以稱之爲聚合。
另外每隻大雁都有兩隻翅膀,大雁與雁翅的關係就叫做組合。
由此可見:
聚合的關係明顯沒有組合緊密,大雁不會因爲它們的羣主將雁羣解散而無法生存;
而雁翅就無法脫離大雁而單獨生存——組合關係的類具有相同的生命週期。
聚合關係圖:
組合關係圖:
在代碼中表現如下:
<span style="font-size:18px;">namespace DEMO
{
/// <summary>
/// 雁羣
/// </summary>
class GooseGroup
{
public Goosegoose;
publicGooseGroup(Goose goose) {
this.goose= goose;
}
}
/// <summary>
/// 大雁
/// </summary>
class Goose
{
publicWing wing;
publicGoose() {
wing = new Wing();
}
}
}</span>
這兩種關係的區別是:
1.構造函數不同
聚合類的構造函數中包含另一個類的實例作爲參數
因爲構造函數中傳遞另一個類的實例,因此大雁類可以脫離雁羣類獨立存在。
組合類的構造函數包含另一個類的實例化
因爲在構造函數中進行實例化,因此兩者緊密耦合在一起,同生同滅,翅膀類不能脫離大雁類存在。
2.信息的封裝性不同
在聚合關係中,客戶端可以同時瞭解GooseGroup類和Goose類,因爲他們是獨立的。
在組合關係中,客戶端只認識大雁類,根本不知道翅膀類的存在,因爲翅膀類被嚴密地封裝在大雁類中。
總結:
對於繼承、實現這兩種關係沒多少疑問,他們體現的是一種類與類、或者類與接口間的縱向關係;其他的四者關係則體現的是類與類、或者類與接口間的引用、橫向關係,是比較難區分的,有很多事物間的關係要想準備定位是很難的,前面也提到,這幾種關係都是語義級別的,所以從代碼層面並不能完全區分各種關係;但總的來說,後幾種關係所表現的強弱程度依次爲:組合>聚合>依賴。
————————————————
版權聲明:本文爲CSDN博主「張宏傑」的原創文章,遵循CC 4.0 BY-SA版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/zhanghongjie0302/article/details/39672859