uml类图
uml类图是一种结构图,用于描述一个系统的静态结构,类图以反映类结构和类之间的关系为目的,来描述层级结构,是一种建模方式
描述类的属性的可见性:
UML中,可见性分为4级
1、public 公用的 :用+ 前缀表示 ,该属性对所有类可见
2、protected 受保护的:用 # 前缀表示,对该类的子孙可见
3、private 私有的:用- 前缀表示,只对该类本身可见
4、package 包的:用 ~ 前缀表示,只对同一包声明的其他类可见
类图中的关系
1、类
类是对现实世界一组具有相同特征的物体的一种抽象,在编程中是实现信息封装的基础,是一种用户定义的引用数据类型。(类的实例叫对象)
2、接口
接口是一种特殊的类,具有类的结构但不可被实例化,只可以被实现(继承)。
3、类图中的关系
(1)继承(泛化)
当类A继承类B,我们就说类A是类B 的泛化(泛化和继承同义)
简单例子:
书籍都可以传播知识,电子书也是书,但是电子书有一般书籍没有的特性,它是电子的。
//书类
type Book struct{
int spreadKnowledge//假定spreadKnowledge为int
}
//电子书类
type eBook stuct{
Book//表示继承自Book(书类)
}
//电子书特有的特性,电子版
func(b*eBook) electronic(){
}
画图时,我们采用「带空心三角箭头的实线」表示继承关系,箭头由「继承类」指向 「被继承类」。
(2)实现
当 类A 具有 接口I 的所有方法,我们就说 类A 实现了 接口I。
简单例子:
只要是能吃的就是 食物,而 面包、饭 都是能吃的,所以可以说 面包、米饭 实现了 食物 这个接口。
// 食物类
type Food interface {
BeEaten()
}
// 面包类
type Bread struct {
// ...
}
func (b *Bread) BeEaten() {
print("吃了面包")
}
// 饭类
type Rice struct {
// ...
}
func (r *Rice) BeEaten() {
print("吃了饭")
}
画图时,我们采用「带空心三角箭头的虚线」表示实现关系,箭头由「实现类」指向 「接口」。
(3)组合
当 类A 中存在 类B 的成员,且这个成员在 类A 初始化完毕时就已经存在,我们就说 类A 组合了 类B。
简单例子:
人都有头发,而且是与生俱来的。
// 人 类
type Person struct {
hair hair
}
// 相当于 Person 的构造函数
func newPerson() person{
return person{
newHair(), // 人出生就有头发
}
}
// 头发类
type hair struct {
// ...
}
// 相当于 hair 的构造函数
func Newhair() hair{
return hair{}
}
画图时,我们采用「带实心棱形箭头的实线」表示组合关系,箭头由「被组合类」指向 「组合类」。
(4)聚合
当 类A 中存在 类B 的成员,且这个成员可通过 Set 方法进行设定,我们就说 类A 聚合了 类B。
简单例子:
富豪去 4S 店买车,当富豪没买时,他处于没车的状态,买了之后,他才进入有车的状态。
`// 富豪类
type RichPerson struct {
car Car
}
// 富豪买车(假设富豪只能拥有一辆车)
// 这里相当于 Set 方法
func (rp *RichPerson) BuyCar(car Car){
rp.car = car
}
// 车类
type Car struct {
// ...
}
`
画图时,我们采用「带空心棱形箭头的实线」表示聚合关系,箭头由「被聚合类」指向 「聚合类」。
(5)关联——依赖关系的特例
当 类A 中存在 类B 的成员,我们就说 类A 关联了 类B。
关联关系可以是双向的,即 A中有B 且 B中有A。
关联关系也可以是一对多的,即 A 中有 B 的数组。
简单例子:
我有很多个小狗。
// 我 类
type Me struct {
girlFriends []GirlFriend
}
// 小狗 类
type puppy struct {
// ...
}
画图时有以下规则:
采用「带箭头的实线」表示 单向关联,箭头由「关联类」指向 「被关联类」。
采用「实线」表示 双向关联。
可以在「线」的两端标明是 一对一、一对多、多对多 关系。
(6)依赖
当 类A 使用到了 类B,我们就说 类A 依赖于 类B。
什么时候算 类A 使用到了 类B 呢?
类B 是 类A 的成员
类B 是 类A 的某个方法的参数、局部变量、返回值。
简单例子:
猴子偷桃,(猴依赖于桃)
// 猴子类
type Monkey struct {
// ...
}
// 桃子类 是 猴子类 steal 方法的参数。
func(m *Monkey)steal(peach Peach) {
// ...
}
// 桃子类
type Peach struct {
// ...
}
画图时,我们采用「带箭头的虚线」表示依赖关系,箭头由「依赖类」指向 「被依赖类」。
总结
六种关系之间的联系是什么?
其他五种关系都是依赖关系的特例。
组合、聚合关系是关联关系的特例。
聚合 和 组合 有什么差别?
被聚合对象可以在后期传入,而被组合对象在类初始化时就已经存在。
六种关系的图像表示。