UML类图中类之间的6种关系与区别

原文:https://blog.csdn.net/it_zjyang/article/details/51355062

两个类之间的关系分为两种,一种是强关联一种是弱关联,强关联是在编译时期就已经确定的,无法在运行时期动态的改变的关联;弱关联是可以动态地确定并且可以在运行时期动态改变的关联。显然,Java中继承是强关联而聚合是弱关联。

类与类之间的关系可以根据关系的强度依次分为以下五种:


依赖关系(Dependency)---关联关系(Association)---聚合(Aggregation)---组合(Composition)---实现(implements)==泛化(Generalization)

依赖关系

依赖关系是五种关系中耦合最小的一种关系。使用虚线加箭头表示,如下图所示:


代码:

[java] view plain copy
  1. public class Person {  
  2.       
  3.     public void Call(){  
  4.         Phone phone = new Phone();  
  5.     }  
  6.   
  7. }  

[java] view plain copy
  1. public class Phone {  
  2.   
  3. }  


解释:Person 和 Phone之间是没有关系的,但是由于偶尔的需要,Person需要使用Phone,在Person类中的具体方法中需要实例化Phone,这时Person就依赖于Phone.持有Phone类的是Person类的一个方法,而不是Person类,这点是最重要的。



关联关系

关联关系是实线加箭头表示。表示类之间的关系比依赖要强,如下图所示:


代码:
[java] view plain copy
  1. public class Person {  
  2.     //头部是人的一个属性  
  3.     public Head head;  
  4.       
  5.     public Person() {  
  6.         // TODO Auto-generated constructor stub  
  7.     }  
  8. }  

[java] view plain copy
  1. public class Head {  
  2.       
  3.     public Head() {  
  4.         // TODO Auto-generated constructor stub  
  5.     }  
  6.   
  7. }  


解释:Head是作为Person类的一个内部属性来使用,一旦实例化了Person类,同时也实例化了一个Head实例,所以他们的依赖性更强。与关联最大的区别是:依赖时是在类的内部具体方法中使用到另外一个类,而关联则是作为内部属性来用,依赖关系仅当具体方法被调用时才会实例化,比如刚才的Person只有打电话时才调用Phone实例化,而关联是在new一个Person时就同时实例化了一个Head类来作为Person的内部属性.



聚合关系

聚合关系通过一个空心的菱形加箭头表示,如下图所示:


代码:
[java] view plain copy
  1. public class PersonGroup {  
  2.       
  3.     public Person person;  
  4.     //将person作为构造方法的参数传进去  
  5.     public PersonGroup(Person person) {  
  6.         // TODO Auto-generated constructor stub  
  7.         this.person = person;  
  8.     }  
  9.   
  10. }  

[java] view plain copy
  1. public class Person {  
  2.       
  3.     public Person() {  
  4.         // TODO Auto-generated constructor stub  
  5.     }  
  6. }  


解释:Person类是PersonGroup构造方法的参数,因此可以Person类可以完全脱离PersonGroup类而存在,不会因为PersonGroup实例的消亡而消亡,就像现实生活中,人不会因为脱离人群就挂了...



组合关系

组合关系通过一个实心的菱形加箭头表示,如下图所示:


代码:
[java] view plain copy
  1. public class Person {  
  2.       
  3.     public Foot foot;  
  4.       
  5.     public Person() {  
  6.         // TODO Auto-generated constructor stub  
  7.         //在构造方法中实例化  
  8.         foot = new Foot();  
  9.     }  
  10. }  

[java] view plain copy
  1. public class Foot {  
  2.       
  3.     public Foot() {  
  4.         // TODO Auto-generated constructor stub  
  5.     }  
  6.   
  7. }  


解释:
Foot类是在Person类的构造方法中才被具体实例化,一旦Person实例生成,则Foot实例也生成,当Person实例消亡,其Foot实例也消亡,就像现实生活中,生成一个人,并定会伴随着脚的生成,但是如果那个人挂了,它的脚自然而然也就...(怎么听着怪怪-.-)


实现关系

是一种类与接口的关系,表示类是接口所有特征和行为的实现.,如下图所示:

带三角箭头的虚线,箭头指向接口

 




泛化关系

泛化关系通常包含类与类之间的继承关系和类与接口实现关系,如下图所示:
继承:

接口:




总结:以前一直对它们之间的区别模模糊糊,通过查阅和总结写出来的个人经验,希望对大家的理解也有所帮助。

他们之间的区别:

对于继承、实现这两种关系没多少疑问,他们体现的是一种类与类、或者类与接口间的纵向关系;其他的四者关系则体现的是类与类、或者类与接口间的引用、横向关系,是比较难区分的,有很多事物间的关系要想准备定位是很难的,前面也提到,这几种关系都是语义级别的,所以从代码层面并不能完全区分各种关系;

1.聚合与组合

(1)聚合与组合都是一种结合关系,只是额外具有整体-部分的意涵。

(2)部件的生命周期不同

聚合关系中,整件不会拥有部件的生命周期,所以整件删除时,部件不会被删除。再者,多个整件可以共享同一个部件。 
组合关系中,整件拥有部件的生命周期,所以整件删除时,部件一定会跟着删除。而且,多个整件不可以同时间共享同一个部件。

(3)聚合关系是“has-a”关系,组合关系是“contains-a”关系。

2.关联和聚合

(1)表现在代码层面,和关联关系是一致的,只能从语义级别来区分。

(2)关联和聚合的区别主要在语义上,关联的两个对象之间一般是平等的,例如你是我的朋友,聚合则一般不是平等的。

(3)关联是一种结构化的关系,指一种对象和另一种对象有联系。

(4)关联和聚合是视问题域而定的,例如在关心汽车的领域里,轮胎是一定要组合在汽车类中的,因为它离开了汽车就没有意义了。但是在卖轮胎的店铺业务里,就算轮胎离开了汽车,它也是有意义的,这就可以用聚合了。

3.关联和依赖

(1)关联关系中,体现的是两个类、或者类与接口之间语义级别的一种强依赖关系,比如我和我的朋友;这种关系比依赖更强、不存在依赖关系的偶然性、关系也不是临时性的,一般是长期性的,而且双方的关系一般是平等的。

(2)依赖关系中,可以简单的理解,就是一个类A使用到了另一个类B,而这种使用关系是具有偶然性的、临时性的、非常弱的,但是B类的变化会影响到A,是一种弱的关联关系。

4.综合比较

除了继承和实现这两种,剩下的四种关系都是语义级别的,所以从代码层面并不能完全区分各种关系,可以说都是关联关系,只不过有强弱之分

但总的来说,后几种关系所表现的强弱程度依次为:

组合>聚合>关联>依赖;


阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页