UML类图中的五种关系的耦合强弱比较:依赖<关联<聚合<组合<继承
一、依赖关系:
(一)说明
虚线+箭头
可描述为:Uses a
依赖是类的五种关系中耦合最小的一种关系,是一种协助关系。
因为在生成代码的时候,这两个关系类都不会增加属性。
(二)依赖关系图与代码的对应关系
动物类与水类的关系就是依赖关系,两者的存在关系有以下几种:
1 Water是Animal的全局变量,animal可以随处调用对象
2 Water是Animal的某个方法的局部变量
void Animal::Drink() { Water water; //在方法中实例化对象,随着函数返回而销毁 ... }
3 Water类是Animal类的某个方法的返回值
Water Animal::getDrink() { Water water; ... return water; //生命周期依然只是函数返回之前 }
二、关联关系
(一)说明
实线+箭头
可描述为:Has a
关联关系用实线,表示类之间的拥有关系,在生成代码的时候,关联关系的类会增加属性。
(二)关联关系与代码的对应关系
水类和气候类的关联关系
class Water { Water () {} //构造自身 Climate m_climate; //水与气候关联,气候类型的成员 }; class Climate { Climate() {} //构造自身 };
(三)关联关系的种类
1、单向关联: A类和B类单向关联,则A类称为源类,B类称为目标类。源类了解目标类的所有的属性和方法,但目标类并不了解源类的信息。
2、双向关联:A类和B类互有对方的属性和方法
三、聚合和组合(具体的关联关系)
聚合关系:
组合关系:
两者的区别与联系:
1. 聚合关系中,被聚合的类的构造函数必须带聚合类形参,聚合类可以独立于被聚合类而存在,例如一只鸟可以独立于鸟群而生存;组合关系中,被组合类的构造函数中必须先一步构造组合类,后者是前者构造出来的必要条件,是其一部分,不能独立存在,例如翅膀不能独立于鸟而生存。
//1. 聚合关系 class Birds { Bird m_bird; //鸟类作为鸟群类的成员 public: Birds(Bird bird) { m_bird = bird; //构造函数带后者作为参数 ... } }; //2.组合关系 class Bird { Winds winds; //翅膀 public: Bird() { winds = new Winds(); //先构造翅膀,再构造爪子,再构造... ... } };
2. 聚合关系中,客户端可以同时了解鸟群类和鸟类,互相独立;组合关系中,客户端只认识鸟类,根本就不知道翅膀类的存在,因为翅膀类被严密的封装在鸟类中。
三、泛化
(一)说明
实线+箭头
可描述为:Is a
泛化也称继承,子类将继承父类的所有属性和方法,并且可以根据需要对父类进行拓展。
(二)泛化关系示意
相对于父类来说,子类继承父类,子类即父类的泛化,子类继承了父类的所有属性和方法。
继承和组合的优缺点:
类继承是在编译时刻静态定义的,可直接使用,类继承可以较方便地改变父类的实现。但是类继承也有一些不足之处。首先,因为继承在编译时刻就定义了,所以无法在运行时刻改变从父类继承的实现。更糟的是,父类通常至少定义了子类的部分行为,父类的任何改变都可能影响子类的行为。如果继承下来的实现不适合解决新的问题,则父类必须重写或被其他更适合的类替换。这种依赖关系限制了灵活性并最终限制了复用性。
对象组合是通过获得对其他对象的引用而在运行时刻动态定义的。由于组合要求对象具有良好定义的接口,而且,对象只能通过接口访问,所以我们并不破坏封装性;只要类型一致,运行时刻还可以用一个对象来替代另一个对象;更进一步,因为对象的实现是基于接口写的,所以实现上存在较少的依赖关系。
四、实现关系
虚线+箭头
接口的意义是抽向类定义方法,但是并不具体实现。
实例:UML类图的具体例子
原文地址:https://www.cnblogs.com/ingy0923/p/9424884.html