这篇文章是类间关系的下半篇,包含了 关联、聚合和组合 三种关系。建议先食用上篇文章。
上半篇博文戳这里
关联 (Association)
关联关系呢,可以看作是一种依赖的关系(上篇博文我们谈到过,依赖关系的范围实际上很广)。它强调的是,一个类知道另一个类的对象,而非仅仅是实现方法时用到。这个“知道”,往往指的就是在类中以另一个类对象作为成员(C++语言可以是对象本身,也可以是引用或是指针,而在java中就只有使用引用持有对象这一种形式)。而且,就像依赖关系可以是相互的,关联关系也可以是相互的,也可以是一对一或是一对多甚至多对多的。
在类图中,我们使用一条实线来连接彼此。我们在刚刚的类图中加入人类和武器类。为了简化,人类的其他关系以及武器的子类予以省略了。
看图:
在这里,人类将武器作为自己的成员变量,而武器类也将人类作为自己的成员变量。两个类互相“知道对方”。故是一种关联关系。
实现成代码:
java:
//人类
public class Human extends Animal{
private Weapon weapon;
}
//武器
public class Weapon {
private String name;
private Animal belongTo;
}
C+:
//人类
#ifndef HUMAN_H
#define HUMAN_H
#include "Animal.h"
class Weapon;
class Human : public Animal
{
private:
Weapon *weapon;
};
#endif
//武器
#ifndef WEAPON_H
#define WEAPON_H
#include<iostream>
#include<string>
class Human;
class Weapon
{
private:
std::string name;
Human *belongTo;
};
#endif
聚合 (Aggregation)
聚合是一种特殊的关联关系,强调的不仅是一个类知道了另一个类,而且强调了一种整体同部分的关系。但是这个整体同部分是可以给分离的,就想名称所表述的那样,作为部分的类对象仅仅是聚集在另一个类中的。
在类图中,我们使用末端为空心菱形的实线表示聚合关系。
聚合关系很好的表述了人与人群的关系,如图:
代码:
java:
//人类
public class Human extends Animal{
}
//人群
public class Crowd {
private Human members[];
}
C++:
//人群
#ifndef CROWD_H
#define CROWD_H
#include"Human.h"
class Crowd
{
private:
Human *members[];
};
#endif
//人类
#ifndef HUMAN_H
#define HUMAN_H
#include "Animal.h"
class Weapon;
class Human : public Animal
{
private:
Weapon *weapon;
};
#endif
–
组合 (Composite)
组合也是一种特殊的关联,也是强调整体与部分的关系,相较于聚合,组合的程度更深一些。表示一类对象由另一类对象组织而来,而不仅仅是聚集。这样的关系代表着他们之间是不可分割的。一个很直观的判断标准是被包含的对象是否同包含对象同生共死且不易更换。
在类图中,我们常使用末端为实心菱形的实线来表示组合关系。
肢体与人就是很好的组合关系,看图:
有时候我了保证不进行修改,相关变量很可能会使用 final 或者 const 进行修饰
代码:
java:
//人类
public class Human extends Animal{
private final Leg legs[];
}
//肢体类
public class Leg {
}
C++:
//人类
#ifndef HUMAN_H
#define HUMAN_H
#include "Animal.h"
class Leg;
class Human : public Animal
{
private:
Leg * const legs[];
};
#endif
//肢体类
#ifndef LEG_H
#define LEG_H
class Leg{
};
#endif
好啦,所有的六种关系我们就梳理完了,怎么样,有没有很多收获呢。
在最后呢,我们再把刚刚的所有类的关系画在一张图上面。
是否还能分的请这些关系的含义和表示呢。
下一篇博客,我们再来总结一下这些个图示和关系,并尝试着找出他们的一些内在联系。
传送门(施工中~)