目录
基于实例区分类间关系:关联、依赖、泛化、实现
在面向对象设计中,经常会遇到uml类图的建模,我之前也经常搞混关联中的聚合、组合、依赖间的关系。看过之前一位大佬的文章后,发现不能以代码片段来分析类间关系,必须通过上下文来分析。
一、关联关系
类与类之间的通信,让一个类发现另一个类的存在。简单来说,就是一个类与另一个类有关系,例如:教师教授学生,学生受教于教师。关联有普通关联、二元关联、多元关联、受限关联。
1、普通关联
关联关系在UML类图建模中表现为:单向关联,带箭头的实现;双向关联:无箭头的实现。
ps:在startUML和rose等建模工具中,都是以双向箭头表示,需要分别点击箭头两端取消navigable,去除箭头。
代码表示:
//学生类
public class Student {
private Teacher teacher;
}
//教师类
public class Teacher {
private Student[] students;
}
2、组合、聚合(特殊的关联关系)
组合、聚合又称为复合,耦合强度高于关联关系,是一种特殊的关联关系,是一种整体与个体的关系。
区分组合和聚合
1. 聚合强调的是个体聚集成整体,例如:学生与班级的关系,某个学生离开,但是班级还存在,班级消失,学生还在;组合强调的是拥有、“物主”关系,例如:动物和器官的关系,个体与整体有很强的关系,整体不在部分无法存活。
2. 聚合的生命周期独立,互不影响,班级生命周期结束,学生不受印象,反之也一样;组合动物的生命周期结束,器官的生命周期也立刻结束。
3. UML类图区分
聚合在UML类图中是空心菱形箭头,个体指向整体。(has-a关系)
组合在UML类图中是实心菱形箭头,个体指向整体。(contains-a关系)
4.代码中表示:
聚合:
Class.java
package com.hgl.ClassRalation;
import java.util.List;
public class Class {
private List<Student> students;
public Class(List<Student> students){
this.students = students;
}
}
Student.java
package com.hgl.ClassRalation;
public class Student {
...
}
组合:
Animal.java
package com.hgl.ClassRalation;
public class Animal {
private Organ organ;
public Animal(){
organ = new Organ();
}
}
Organ.java
package com.hgl.ClassRalation;
public class Organ {
...
}
二、依赖关系
两个类间在在语义上的连接关系,当一个类依赖了另一个类,被依赖类(提供者)发生改变时会影响到依赖类(客户类)。耦合关系相较于关联更弱,通常出现于客户类的方法属性中,或者局部变量中。
主要使用依赖场景
- 客户类向提供类发送消息(客户类调用了提供者类的静态方法)
- 提供者类是客户类中的局部变量时。
- 提供者作为客户类方法中的参数时。
UML类图与代码中表示
依赖关系在UML类图中的表示为:虚线带箭头,由客户类指向提供者类,(use-a关系)。
Provicer.java
package com.hgl.ClassRalation;
public class Provider {
public void sentMsg(){
}
public static void doSomething(){
}
}
通过设置提供者形参实现依赖
Receiver.java
package com.hgl.ClassRalation;
/**
* 通过设置提供者形参实现依赖
*/
public class Receiver {
public void recv(Provider provider){
provider.sentMsg();
}
}
ps:区分组合、聚合、依赖、关联时,不应该过于关注代码,容易搞混,只需要记住本质:类间关系,比如组合为什么叫组合?个体组成整体,不可分割个体不能独自生存,所以个体生命周期受整体的生命周期影响。
通过客户类向提供类发送消息实现依赖
Receiver.java
package com.hgl.ClassRalation;
/**
* 通过客户类向提供类发送消息
*/
public class Receiver {
public void recv(){
Provider.doSomething();
}
}
通过客户类设置提供者类的局部变量实现依赖
Receiver.java
package com.hgl.ClassRalation;
/**
* 通过设置提供者形参实现依赖
*/
public class Receiver {
public void recv(){
Provider provider = new Provider();
provider.sentMsg();
}
}
三、泛化关系(继承)
泛化关系描述的是一般-特殊关系,特殊建立于一般基础上,在面向对象设计中,一般关系被设计为父类,特殊关系被设计为子类。也就是把一些类中有相同的部分(属性和方法)提取出来,设计为父类,子类继承就可以获取父类的所有信息,提高代码的复用性。子类中也可以定义自己的属性和方法,但是在使用向上转型(用父类定义变量存放子类实例时)不能读取到子类特有的方法。
继承为面向对象语言对于泛化关系的实现,而继承分为单继承和多继承,java语言中只支持单继承,以下也是以单继承实例。
UML和代码表示为
UML中泛化关系用实线,空心三角箭头实心线,子类指向父类,(is-a关系)。
Father.java
package com.hgl.ClassRalation;
public class Father {
public Father(){
System.out.println("father");
}
}
Children.java
package com.hgl.ClassRalation;
public class Children extends Father{
public Children(){
System.out.println("children");
}
}
四、实现关系
实现关系是预先定义一系列操作封装为一种行为规约称为接口,在类中可以使用implement实现定义的接口,实现接口时需要实现接口中的所有方法。接口是一种高级抽象,类可以实现多个接口。
UML和代码表示为
在UML中表示为空心箭头虚线,(starUML中居然只显示直线。。)箭头由类指向接口。
java中继承关系相当于父与子只能单继承(一个子类只有一个父类),而实现关系相当于学生与教师(学生可以有多个教师)。
以上是学习过程总结,如有疏漏之处,还请不吝赐教,让我能更加了解这方面内容,提前感谢。