在學習面向對象、設計對象關係時,依賴、關聯、聚合、組合這四種關係很容易混淆。如何更好地區分和使用它們呢,今天就來梳理一下。
一、依賴(dependency)
依賴關係,是類與類之間的聯結關係,表示一個類依賴於另一個類的定義。
它是一種使用(use-a)關係。
一般使用方法的形參、局部變量、靜態方法來體現。
比如:說人和水的關係,便是依賴關係。人依賴於水,人的生存離不開水,人要使用水。
代碼示例:
/**
* 人 實體類
*/
public class Person {
/**
* 喝水方法
* @param water
*/
public void drinkWater(Water water){
water.outWater();
System.out.println("我在喝水");
}
}
/**
* 水 實體類
*/
public class Water {
public void outWater(){
// TODO
}
}
二、關聯(Association)
關聯關係,是類與類之間的聯結關係,它使一個類知道另一個類的屬性和方法。關聯可以是雙向的,也可以是單向的。
它是一種擁有(has-a)關係。
一般使用成員(實例)變量來體現。
比如:人和衣櫥的關係,一個人擁有一個衣櫥,便是關聯關係。
示例:
public class Person {
// 我的衣櫥,has-a,關聯關係
private Chifforobe chifforobe;
public void setChifforobe(Chifforobe chifforobe) {
this.chifforobe = chifforobe;
}
public Chifforobe getChifforobe() {
return chifforobe;
}
}
/**
* 衣櫥實體類
* @date 2022年9月14日
* @Description
*
*/
public class Chifforobe {
// TODO
}
注意:依賴和關聯的區別在於依賴是使用,關聯是擁有。
三、聚合(Aggregation)
聚合關係,是關聯關係的一種,是強的關聯關係,是羣體與個體的關係。羣體中包含個體,個體可以獨立於羣體而存在。
它是一種擁有(has-a)關係。
聚合關係也是通過成員(實例)變量體現的。
比如:衣櫥是裝衣服的容器,它代表衣服的羣體,一件衣服離開衣櫥依舊可以單獨存在。
示例:
import java.util.ArrayList;
import java.util.List;
/**
* 衣櫥實體類
* @date 2022年9月14日
* @Description
*
*/
public class Chifforobe {
// 衣櫥裏的衣物集合,衣物集合和具體的衣物,組合關係,has-a,羣體與個體的關係
private List<Clothes> clothesList = new ArrayList<Clothes>();
// 添加一個衣物
public void add(Clothes clothes){
clothesList.add(clothes);
}
// 拿走一個衣物
public void remove(Clothes clothes){
clothesList.remove(clothes);
}
// 整理衣櫥的衣物
public void clearUp(){
clothesList.forEach(clothes->clothes.show());
}
}
/**
* 衣服接口
* @date 2022年9月14日
* @Description
*
*/
public interface Clothes {
// 放入
void putIn();
// 展示
void show();
}
/**
* 裙子實體類
* @date 2022年9月14日
* @Description
*
*/
public class Skirt implements Clothes{
@Override
public void putIn() {
System.out.println("買了一件裙子");
}
@Override
public void show() {
System.out.println("有一件裙子");
}
}
/**
* 帽子實體類
* @date 2022年9月14日
* @Description
*
*/
public class Cap implements Clothes{
@Override
public void putIn() {
System.out.println("買了一頂帽子");
}
@Override
public void show() {
System.out.println("有一頂帽子");
}
}
注意:關聯關係所涉及的兩個類是處在同一層次上的。而在聚合關係中,兩個類是處在不平等層次上的,一個代表羣體,另一個代表個體。
四、組合(Composition)
組合關係,是關聯關係的一種,是比聚合關係更強的關聯關係。它要求聚合關係中代表整體的對象負責代表部分對象的生命週期。也就是說,在組合關係中,部分和整體的生命週期是一樣的。
它是一種整體與部分(part-of)關係。
一般使用成員(實例)變量來體現。
比如:人和胳膊的關係,是整體和部分的關係,胳膊是屬於人體的一部分,並且胳膊和人體擁有同樣的生命週期,人活着胳膊纔有可能活着。
示例:
import java.util.ArrayList;
import java.util.List;
/**
* 人實體類
* @date 2022年9月14日
* @Description
*
*/
public class Person {
// 我的胳膊,組合,part-of,部分與整體的關係
private List<Arm> arms;
public Person(){
arms = new ArrayList<Arm>();
arms.add(new Arm("左"));
arms.add(new Arm("右"));
}
public List<Arm> getArms() {
return arms;
}
}
/**
* 胳膊實體類
* @date 2022年9月14日
* @Description
*
*/
public class Arm {
private String direction;
public Arm(String direction) {
this.direction = direction;
}
public void bump(String name){
System.out.println("我的" + direction + "胳膊 碰到了" + name + ",好疼呀!");
}
}
注意:在關聯關係中,所涉及的兩個類是處在同一層次上的。而在組合關係中,兩個類是處在不平等層次上的,一個代表整體,另一個代表部分。
測試代碼:
Person me = new Person();
// 人和水的關係,人依賴於誰,use-a使用關係
me.drinkWater(new Water());
// 創建我的衣櫥,has-a擁有關係
me.setChifforobe(new Chifforobe());
// 往衣櫥裏放衣物,衣櫥和衣服的關係,聚合關係 has-a,衣櫥和衣服可以獨立分開,獨立存在
me.getChifforobe().add(new Cap());
me.getChifforobe().add(new Skirt());
// 整理衣櫃
me.getChifforobe().clearUp();
// 我的胳膊碰到了桌角,人和胳膊的關係,part-of,胳膊是人的一部分,擁有同樣的生命週期
me.getArms().get(0).bump("桌角");
聚合和組合的區別
1、依賴性區別
聚合關係中的兩個類可以是單獨存在的,不會相互影響,被關聯的一方可以獨立於另一方存在,依賴性不強。
而組合關係中的兩個類是高度依賴於彼此,它們之間相互影響。
2、關係類型區別
聚合代表了擁有has-a關係,組合代表了整體部分part-of關係;
3、關聯強度區別
聚合關係是比較弱的關聯關係,組合關係是比較強的關聯關係。
4、生命週期的不同
在聚合關係中,兩個類的生命週期是不一樣的;在組合關係中,兩個類的生命週期是一樣的。
最後總結
依賴和關聯分不清,主要看是使用(Use-a)還是擁有(Has-a),使用是依賴,擁有是關聯。
聚合和組合分不清,主要看生命週期是否捆綁,生命週期綁在一起的是組合,生命週期不是綁在一起的是聚合。
以上便是我的理解,希望對你有用,同時也分享給其他需要的朋友。