一、聚合与组合

继承是面向对象编程三大特性之一,通过继承,子类可以继承父类非private的属性和方法,大大提高代码复用性和开发效率。

但继承也有众多缺点,

  • 比如使得子类与父类过度耦合,当父类发生调整会影响所有子类都进行检查,必要时也要同时进行调整
  • 子类对父类同时也具有了侵入性,需要重载所有父类的属性和方法,这和迪米特法则是违背的
  • 同时子类由于需要继承父类所有属性和方法,这时候子类就会显得笨拙,例如圆形三角形和矩形都可以继承父类图形类,但如果给图形类增加了长和宽或者半径的属性,那三角形圆形矩形则继承了无用的属性,此时应调整继承方式仅限方法,不具有一般性的属性不要放到父类中

在面对这些缺点时,里氏替换原则提出了使用聚合或组合的方式来减少继承的使用。

聚合是耦合度相对组合偏低的依赖关系,两者生命周期可以不同,可以理解为A类与B类存在紧密关系,但并非不可或缺。就像人一定需要身份证,但可能处于身份证丢失补办状态。

实现方式在A类中私有化B类对象,通过set方法赋值,然后通过该私有化对象实现B类中的方法

public class A{private B b;public void setB(B b){this.b = b;}}

组合是耦合度更高的关联关系,两者会具有相同的生命周期,可以理解为A类与B类存在同声同灭的关系,就像人一定要有心脏,没有心脏就肯定活不了。。。实现方式

可以在A类构造器中将B类作为参数,

public class A{public A(B b){}}

或者饿汉式加载B对象

public class A{private B b = new B();}

二、UML语言补充

1、关联关系

关联(Assocition)关系是类与类之间最常见的一种关系,它是一种结构化的关系,表示一类对象与另一类对象之间有联系,如汽车和轮胎、师傅和徒弟、班级和学生等。在UML类图中,用实线连接有关联关系的对象所对应的类,在Java中通常将一个类的对象作为另一个类的成员变量。关联关系分单向关联、双向关联、自关联,逐一看一下。

1、单向关联关系

单向关联指的是关联只有一个方向,比如顾客(Customer)拥有地址(Address),其Java实现为:

public class Address
{}
public class Customer
{private Address address;
}

UML的画法为:

2、双向关联关系

默认情况下的关联都是双向的,比如顾客(Customer)购买商品(Product),反之,卖出去的商品总是与某个顾客与之相关联,这就是双向关联。Java类的写法为:

public class Product
{private Customer customer;
}
public class Customer
{private Product[] product;
}

对应的UML类图应当是:

3、自关联关系

自关联,指的就是对象中的属性为对象本身,这在链表中非常常见,单向链表Node中会维护一个它的前驱Node,双向链表Node中会维护一个它的前驱Node和一个它的后继Node。就以单向链表为例,它的Java写法为:

public class Node
{private Node nextNode;
}

对应的UML类图应当是:

4、聚合关系

聚合(Aggregation)关系表示整体与部分的关系。在聚合关系中,成员对象是整体的一部分,但是成员对象可以脱离整体对象独立存在。在UML中,聚合关系用带空心菱形的直线表示,如汽车(Car)与引擎(Engine)、轮胎(Wheel)、车灯(Light),Java表示为:

public class Engine
{}
public class Wheel
{}
public class Light
{}
public class Car {private Engine engine;private Light light;private Wheel wheel;public void setEngine(Engine engine) {this.engine = engine;}public void setLight(Light light) {this.light = light;}public void setWheel(Wheel wheel) {this.wheel = wheel;}public void drive(){}
}

对应的UML类图为:

代码实现聚合关系,成员对象通常以构造方法、Setter方法的方式注入到整体对象之中。

5、组合关系

组合(Composition)关系也表示的是一种整体和部分的关系,但是在组合关系中整体对象可以控制成员对象的生命周期,一旦整体对象不存在,成员对象也不存在,整体对象和成员对象之间具有同生共死的关系。在UML中组合关系用带实心菱形的直线表示。

比如人的头(Head)和嘴巴(Mouth)、鼻子(Nose),嘴巴和鼻子是头的组成部分之一,一旦头没了,嘴巴也没了,因此头和嘴巴、鼻子是组合关系,Java表示为:

public class Mouth
{}
public class Nose
{}
public class Head
{private Mouth mouth;private Nose nose;public Head(){mouth = new Mouth();nose = new Nose();}public void shake(){}
}

其UML的表示方法为:

代码实现组合关系,通常在整体类的构造方法中直接实例化成员类,这是因为组合关系的整体和部分是共生关系,如果通过外部注入,那么即使整体不存在,那么部分还是存在的,这就相当于变成了一种聚合关系了。

6、依赖关系

依赖(Dependency)关系是一种使用关系,特定事物的改变有可能会影响到使用该事物的其他事物,在需要表示一个事物使用另一个事物时使用依赖关系,大多数情况下依赖关系体现在某个类的方法使用另一个类的对象作为参数。在UML中,依赖关系用带箭头的虚线表示,由依赖的一方指向被依赖的一方。

比如,驾驶员(Driver)开车,Driver类的drive()方法将车(Car)的对象作为一个参数传递,以便在drive()方法中能够调用car的move()方法,且驾驶员的drive()方法依赖车的move()方法,因此也可以说Driver依赖Car,Java代码为:

public interface Car
{public void move();
}
public class Driver
{public void drive(Car car){car.move();}
}

其UML的画法为:

依赖关系通常通过三种方式来实现:

将一个类的对象作为另一个类中方法的参数
在一个类的方法中将另一个类的对象作为其对象的局部变量
在一个类的方法中调用另一个类的静态方法

7、关联关系、聚合关系、组合关系之间的区别

从上文可以看出,关联关系、聚合关系和组合关系三者之间比较相似,本文的最后就来总结一下这三者之间的区别。

关联和聚合的区别主要在于语义上:关联的两个对象之间一般是平等的,聚合则一般是不平等的。

聚合和组合的区别则在语义和实现上都有差别:组合的两个对象之间生命周期有很大的关联,被组合的对象在组合对象创建的同时或者创建之后创建,在组合对象销毁之前销毁,一般来说被组合对象不能脱离组合对象独立存在,而且也只能属于一个组合对象;聚合则不一样,被聚合的对象可以属于多个聚合对象。

参考自:

UML类图:关联、聚合、组合、依赖

聚合与组合的意义和区别 (Java)

Java中的聚合与组合相关推荐

  1. DDD中的聚合和UML中的聚合以及组合的关系

    UML: 聚合关系:成员对象是整体的一部分,但是成员对象可以脱离整体对象独立存在. 如汽车(Car)与引擎(Engine).轮胎(Wheel).车灯(Light)之间的关系为聚合关系,引擎.轮胎.车灯 ...

  2. Java中的多重继承与组合vs继承

    有时我写了几篇有关Java 继承 , 接口和组成的文章. 在这篇文章中,我们将研究多重继承,然后学习组成优于继承的好处. Java中的多重继承 多重继承是创建具有多个超类的单个类的能力. 与其他一些流 ...

  3. Java中的继承与组合

    本文主要说明Java中继承与组合的概念,以及它们之间的联系与区别.首先文章会给出一小段代码示例,用于展示到底什么是继承.然后演示如何通过"组合"来改进这种继承的设计机制.最后总结这 ...

  4. UML中的聚合与组合

    总结一下聚合和组合的关系. 组合关系(Composition):部分和整体之间具有相同的生命周期,当整体消亡后,部分也将消亡.就像大雁的翅膀和大雁是组合关系.代码实现时,部分类在整体类的构造函数中被构 ...

  5. 浅谈UML中的聚合与组合

    欢迎大家关注我的新书<Spring Boot趣味实战课> 京东 当当 天猫 ​ 大家都知道UML的类图中一般包含五种关系即  关联 聚合 组合 泛化 依赖  有些人可能会感觉组合跟聚合有点 ...

  6. 继承、实现、依赖、关联、聚合、组合的联系与区别

    继承 指的是一个类(称为子类.子接口)继承另外的一个类(称为父类.父接口)的功能,并可以增加它自己的新功能的能力,继承是类与类或者接口与接口之间最常见的关系:在Java中此类关系通过关键字extend ...

  7. java中字符串后加Box_字符串未显示在JavaFX中ComboBox的Tableview上

    我一直在尝试在Java中显示我从组合框到表视图的选择 . 我花了好几个小时都在寻找解决方案,但没有用 . 我没有任何错误,但我似乎无法在TableView上显示一个字符串 . 我想请求帮助 . Mai ...

  8. Java中的组合、聚合和关联关系

    1.介绍 对象之间在现实生活和编程中都有关系.有时很难理解或实现这些关系. 在本教程中,我们将重点介绍 Java 的三种关系类型,这些关系有时很容易混合:组合.聚合和关联. 2.组合 组成是一种&qu ...

  9. UML中几种类间关系:继承、实现、依赖、关联、聚合、组合的联系与区别

    zz from: http://dev.firnow.com/course/3_program/java/javajs/20090219/155939.html UML中几种类间关系:继承.实现.依赖 ...

最新文章

  1. .Net 程序员面试 C# 语言篇 (回答Scott Hanselman的问题)
  2. perl脚本发送邮件
  3. Android ActionBar完全解析,使用官方推荐的最佳导航栏(上)
  4. 职工考勤管理信息系统数据库课设_数据库课程设计--职工考勤管理信息系统
  5. 程序员你写的代码,被人挖出了黑产
  6. .net Reflection(反射)- 二
  7. Git部署远程仓库至github
  8. vue中的$event
  9. 可视化网络监控软件OpManager获选″IT运维产品之星”
  10. 一张图秒懂Android事件分发机制
  11. 公安大数据可视化指挥决策平台
  12. android手机如何截屏,安卓手机怎么截屏(教你华为手机5种截图技巧)
  13. 用Arduino播放音乐
  14. 20 C++ 秒数转换时分秒
  15. 数字信号处理实验二:DFT的共轭对称性及应用
  16. 论苹果与安卓系统争霸
  17. 材料研究生转行做什么?
  18. teradata ttu_SQL语句笔记之Teradata
  19. 三年一跳槽、拒绝“唯学历”,火速 Get 这份程序员求生指南!
  20. TOMCAT6.0配置(虚拟目录的设置+多域名绑定)

热门文章

  1. github pages 功能开启
  2. Java数组介绍(一维数组和二维数组)
  3. c语言德•摩根定律编程,数学集合–德摩根定律
  4. NGUI(3) UIWidget
  5. 关于 Chrome插件安装时程序包无效:CRX_HEADER_INVALID 的解决方法
  6. Pycharm中如何修改光标大小?
  7. Linux的安全扫描Nikto安装
  8. android调用网络打印机,Android下通过wifi调用打印机打印
  9. HTMLCSSJS学习
  10. 域格模组抓取log解析dump方法