UML中类之间的几种关系
生活随笔
收集整理的這篇文章主要介紹了
UML中类之间的几种关系
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
類之間可能存在以下幾種關系:關聯(association)、依賴(dependency)、聚合(Aggregation,也有的稱聚集)、組合(Composition)、泛化(generalization,也有的稱繼承)、實現(Realization)。 關聯是指兩個類之間存在某種特定的對應關系,例如客戶和訂單,一個訂單只能屬于某個客戶,一個客戶可能會有多張訂單。根據方向,分為單向和雙向。根據對應的數量分為一對一、一對多、多對多等。對應的UML圖如下所示:
??? 關聯關系用實線+箭頭表示。上圖顯示Customer和Order是雙向一對多關聯關系。對應的Java代碼如下所示: ?class Customer {
private Integer id;
private String name; ??private Set<Order> orders; ??public Set<Order> getOrders() {
return orders;
} ??public void setOrders(Set<Order> orders) {
this.orders = orders;
} ?} ?class Order {
private Integer id;
private float money; ??private Customer customer; ??public Customer getCustomer() {
return customer;
} ??public void setCustomer(Customer customer) {
this.customer = customer;
} ?} Customer和Order是雙向一對多關聯關系,那么在Customer中應該有Order的集合,在Order中應該Customer的屬性。 依賴指的是類之間的調用關系。類A訪問類B的屬性或方法,或者類A負責實例化類B,那么就說類A依賴于類B。和關聯關系不同的是,無需在類A中定義類B類型的屬性。例如自行車和打氣筒,自行車通過打氣筒來充氣,那么就需要調用打氣筒的充氣方法。對應的UML圖如下所示:
??? 依賴關系用虛線+箭頭表示。上圖顯示Bicycle和Pump是依賴關系,Bicycle依賴于Pump。對應的Java代碼如下所示: ?class Bicycle {
public void expand(Pump pump) {
pump.blow();
}
} ?class Pump {
public void blow() {
System.out.println("正在充氣......");
}
} 打氣筒并不屬于某個特定的自行車,一個打氣筒可以為多個自行車提供充氣的服務。在Bicycle中不需要定義Pump類型的屬性,而是將傳遞了一個Pump類型的參數到Bicycle的方法中。 聚合是整體與部分之間的關系。例如計算機和主板,計算機是一個整體,主板是其中的一部分,主板、顯卡、顯示器等部件組成了計算機。對應的UML圖如下所示:
??? 聚合使用空心菱形+實線表示。上圖顯示Computer是由MainBoard和DisplayCard等組成的。對應的Java代碼如下所示:
?class Computer {
private MainBoard mainBoard;
private DisplayCard displayCard;
public void on() {
System.out.println("開啟計算機......");
} ??public void close() {
System.out.println("關閉計算機......");
} ??public void run() {
System.out.println("計算機正在運行......");
}
} ?class MainBoard {
public void control() {
System.out.println("控制計算機......");
}
} ?class DisplayCard {
public void display() {
System.out.println("計算顯示數據......");
}
} 計算機由主板、顯卡等部件組成,所以在Computer中定義了MainBoard和DisplayCard類型的屬性。 聚合中類之間可以獨立出來,比如一塊主板可以狀態A計算機上,也可以裝在B計算機上。也就是說這塊主板離開A計算機之后仍然是有意義的。 組合中的類也是整體與部分的關系,與聚合不同的而是,其中的類不能對立出來。例如一個人由頭、手、腿和軀干等組成,如果這個頭離開了這個人,那么這個頭就沒有任何意義了。對應的UML圖如下所示: 組合使用實心菱形和實線表示。上圖表示People是由Head、Hand、Leg等組成。對應的Java代碼如下所示: ?class People {
private Head head;
private Hand hand;
private Leg leg; ??public void think() {
head.think();
} ??public void holdThing() {
hand.holdThing();
} ??public void walk() {
leg.walk();
}
} ?class Head {
public void think() {
System.out.println("思考......");
}
} ?class Hand {
public void holdThing() {
System.out.println("拿東西......");
}
} ?class Leg {
public void walk() {
System.out.println("走路......");
}
} People和Head、Hand、Leg是不可分割的,Head、Hand、Leg離開了People沒有任何實際意義。在People中定義了Head、Hand、Leg類型的屬性,組合也可以看成是聚合的一種特殊形式。 聚合和組合的代碼幾乎相同,單憑代碼是無法區分兩個類之間是聚合還是組合的關系的。所以就需要結合實際的業務環境來區分。例如汽車和輪胎,車主買了一輛汽車,上邊肯定是由輪胎的,在這個業務中,輪胎和汽車是組合關系,它們分開就沒有實際意義了。在汽車修理店,汽車可以更換輪胎,所以在汽修店的業務環境中,汽車和輪胎就是聚合的關系,輪胎離開汽車是有業務意義的。 泛化比較好理解,就是兩個類之間具有繼承關系。例如人和學生,學生繼承了人,除過具有人的一般的屬性和方法之外,他還要有學習的方法。對應的UML圖如下所示:
??? 泛化用空心三角形+實線表示。上圖表示Student繼承People。對應的Java代碼如下所示: ?class People {
protected String name;
protected String sex;
protected Date birthday; ??public void eat() {
System.out.println(name + "正在吃飯......");
} ??public void drink() {
System.out.println(name + "正在喝水......");
} ??public void sleep() {
System.out.println(name + "正在休息......");
}
} ?class Student extends People {
public void study() {
System.out.println(name + "正在學習......");
}
} Student繼承自People,并且多了一個study的方法。 實現即一個類實現了某個接口。對應的UML圖如下所示:
??? 實現用三角形箭頭和虛線表示。上圖表示類CarDriver和PlaneDriver都實現了Driver接口。對應的Java代碼如下所示: public interface Driver {
void drive();
}
class CarDriver implements Driver { ??public void drive() {
System.out.println("駕駛汽車......");
} ?} ?class PlaneDriver implements Driver { ??public void drive() {
System.out.println("駕駛飛機......");
} ?} 值得注意的是,關聯、依賴、聚合、組合的關系很容易搞混。當對象A和對象B之間存在關聯、依賴、聚合或者組合關系時,對象A都有可能調用對象B的方法。這是它們的相同之處。另外它們還有自己的特征。 對于兩個相對獨立的對象A和B,當一個對象A的實例與B的實例存在固定的對應關系時,這兩個對象之間為關聯關系。代碼中表現為在A中定義了B類型的屬性。 對于兩個相對獨立的對象A和B,當一個對象A負責構造對象B的實例,或者調用對象B提供的服務時,這兩個對象之間主要體現為依賴關系。代碼中的表現即將B類型的參數傳入A的方法中,而不是在A中定義B類型的屬性。 聚合、組合與關聯在代碼中并沒有明顯的區別,主要看實際的業務環境,根據代碼所處的實際業務環境來判斷它們之間的關系。同樣的兩個類,處在不同的業務環境中,可能它們的關系也不相同。
??? 關聯關系用實線+箭頭表示。上圖顯示Customer和Order是雙向一對多關聯關系。對應的Java代碼如下所示: ?class Customer {
private Integer id;
private String name; ??private Set<Order> orders; ??public Set<Order> getOrders() {
return orders;
} ??public void setOrders(Set<Order> orders) {
this.orders = orders;
} ?} ?class Order {
private Integer id;
private float money; ??private Customer customer; ??public Customer getCustomer() {
return customer;
} ??public void setCustomer(Customer customer) {
this.customer = customer;
} ?} Customer和Order是雙向一對多關聯關系,那么在Customer中應該有Order的集合,在Order中應該Customer的屬性。 依賴指的是類之間的調用關系。類A訪問類B的屬性或方法,或者類A負責實例化類B,那么就說類A依賴于類B。和關聯關系不同的是,無需在類A中定義類B類型的屬性。例如自行車和打氣筒,自行車通過打氣筒來充氣,那么就需要調用打氣筒的充氣方法。對應的UML圖如下所示:
??? 依賴關系用虛線+箭頭表示。上圖顯示Bicycle和Pump是依賴關系,Bicycle依賴于Pump。對應的Java代碼如下所示: ?class Bicycle {
public void expand(Pump pump) {
pump.blow();
}
} ?class Pump {
public void blow() {
System.out.println("正在充氣......");
}
} 打氣筒并不屬于某個特定的自行車,一個打氣筒可以為多個自行車提供充氣的服務。在Bicycle中不需要定義Pump類型的屬性,而是將傳遞了一個Pump類型的參數到Bicycle的方法中。 聚合是整體與部分之間的關系。例如計算機和主板,計算機是一個整體,主板是其中的一部分,主板、顯卡、顯示器等部件組成了計算機。對應的UML圖如下所示:
??? 聚合使用空心菱形+實線表示。上圖顯示Computer是由MainBoard和DisplayCard等組成的。對應的Java代碼如下所示:
?class Computer {
private MainBoard mainBoard;
private DisplayCard displayCard;
public void on() {
System.out.println("開啟計算機......");
} ??public void close() {
System.out.println("關閉計算機......");
} ??public void run() {
System.out.println("計算機正在運行......");
}
} ?class MainBoard {
public void control() {
System.out.println("控制計算機......");
}
} ?class DisplayCard {
public void display() {
System.out.println("計算顯示數據......");
}
} 計算機由主板、顯卡等部件組成,所以在Computer中定義了MainBoard和DisplayCard類型的屬性。 聚合中類之間可以獨立出來,比如一塊主板可以狀態A計算機上,也可以裝在B計算機上。也就是說這塊主板離開A計算機之后仍然是有意義的。 組合中的類也是整體與部分的關系,與聚合不同的而是,其中的類不能對立出來。例如一個人由頭、手、腿和軀干等組成,如果這個頭離開了這個人,那么這個頭就沒有任何意義了。對應的UML圖如下所示: 組合使用實心菱形和實線表示。上圖表示People是由Head、Hand、Leg等組成。對應的Java代碼如下所示: ?class People {
private Head head;
private Hand hand;
private Leg leg; ??public void think() {
head.think();
} ??public void holdThing() {
hand.holdThing();
} ??public void walk() {
leg.walk();
}
} ?class Head {
public void think() {
System.out.println("思考......");
}
} ?class Hand {
public void holdThing() {
System.out.println("拿東西......");
}
} ?class Leg {
public void walk() {
System.out.println("走路......");
}
} People和Head、Hand、Leg是不可分割的,Head、Hand、Leg離開了People沒有任何實際意義。在People中定義了Head、Hand、Leg類型的屬性,組合也可以看成是聚合的一種特殊形式。 聚合和組合的代碼幾乎相同,單憑代碼是無法區分兩個類之間是聚合還是組合的關系的。所以就需要結合實際的業務環境來區分。例如汽車和輪胎,車主買了一輛汽車,上邊肯定是由輪胎的,在這個業務中,輪胎和汽車是組合關系,它們分開就沒有實際意義了。在汽車修理店,汽車可以更換輪胎,所以在汽修店的業務環境中,汽車和輪胎就是聚合的關系,輪胎離開汽車是有業務意義的。 泛化比較好理解,就是兩個類之間具有繼承關系。例如人和學生,學生繼承了人,除過具有人的一般的屬性和方法之外,他還要有學習的方法。對應的UML圖如下所示:
??? 泛化用空心三角形+實線表示。上圖表示Student繼承People。對應的Java代碼如下所示: ?class People {
protected String name;
protected String sex;
protected Date birthday; ??public void eat() {
System.out.println(name + "正在吃飯......");
} ??public void drink() {
System.out.println(name + "正在喝水......");
} ??public void sleep() {
System.out.println(name + "正在休息......");
}
} ?class Student extends People {
public void study() {
System.out.println(name + "正在學習......");
}
} Student繼承自People,并且多了一個study的方法。 實現即一個類實現了某個接口。對應的UML圖如下所示:
??? 實現用三角形箭頭和虛線表示。上圖表示類CarDriver和PlaneDriver都實現了Driver接口。對應的Java代碼如下所示: public interface Driver {
void drive();
}
class CarDriver implements Driver { ??public void drive() {
System.out.println("駕駛汽車......");
} ?} ?class PlaneDriver implements Driver { ??public void drive() {
System.out.println("駕駛飛機......");
} ?} 值得注意的是,關聯、依賴、聚合、組合的關系很容易搞混。當對象A和對象B之間存在關聯、依賴、聚合或者組合關系時,對象A都有可能調用對象B的方法。這是它們的相同之處。另外它們還有自己的特征。 對于兩個相對獨立的對象A和B,當一個對象A的實例與B的實例存在固定的對應關系時,這兩個對象之間為關聯關系。代碼中表現為在A中定義了B類型的屬性。 對于兩個相對獨立的對象A和B,當一個對象A負責構造對象B的實例,或者調用對象B提供的服務時,這兩個對象之間主要體現為依賴關系。代碼中的表現即將B類型的參數傳入A的方法中,而不是在A中定義B類型的屬性。 聚合、組合與關聯在代碼中并沒有明顯的區別,主要看實際的業務環境,根據代碼所處的實際業務環境來判斷它們之間的關系。同樣的兩個類,處在不同的業務環境中,可能它們的關系也不相同。
總結
以上是生活随笔為你收集整理的UML中类之间的几种关系的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Java实现文件上传-按钮弹出上传页面
- 下一篇: 让pt-slave-restart支持M