java 聚合和组合的区别?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java 聚合和组合的区别?相关的知识,希望对你有一定的参考价值。
请高手帮忙解释一下```最好能用简单的代码来说明下!谢谢了!
聚合(Aggregation) 关系是关联关系的一种,是强的关联关系。聚合是整体和个体之间的关系。例如,汽车类与引擎类、轮胎类,以及其它的零件类之间的关系便整体和个体的关系。与关联关系一样,聚合关系也是通过实例变量实现的。但是关联关系所涉及的两个类是处在同一层次上的,而在聚合关系中,两个类是处在不平等层次上的,一个代表整体,另一个代表部分
组合(Composition) 关系是关联关系的一种,是比聚合关系强的关系。它要求普通的聚合关系中代表整体的对象负责代表部分对象的生命周期,组合关系是不能共享的。代表整体的对象需要负责保持部分对象和存活,在一些情况下将负责代表部分的对象湮灭掉。代表整体的对象可以将代表部分的对象传递给另一个对象,由后者负责此对象的生命周期。换言之,代表部分的对象在每一个时刻只能与一个对象发生组合关系,由后者排他地负责生命周期。部分和整体的生命周期一样。
以上关系的耦合度依次增强(关于耦合度的概念将在以后具体讨论,这里可以暂时理解为当一个类发生变更时,对其他类造成的影响程度,影响越小则耦合度越弱,影响越大耦合度越强)。由定义我们已经知道,依赖关系实际上是一种比较弱的关联,聚合是一种比较强的关联,而组合则是一种更强的关联,所以笼统的来区分的话,实际上这四种关系、都是关联关系。
聚合关系是是一种比较强的关联关系,java中一般使用成员变量形式实现。对象之间存在着整体与部分的关系。例如上例中
//使用成员变量形式实现聚合关系
Car mycar;
public void drive()
mycar.run();
假如给上面代码赋予如下语义:车是一辆私家车,是司机财产的一部分。则相同的代码即表示聚合关系了。聚合关系一般使用setter方法给成员变量赋值。
假如赋予如下语义:车是司机的必须有的财产,要想成为一个司机必须要先有辆车,车要是没了,司机也不想活了。而且司机要是不干司机了,这个车就砸了,别人谁也别想用。那就表示组合关系了。一般来说,为了表示组合关系,常常会使用构造方法来达到初始化的目的,例如上例中,加上一个以Car为参数的构造方法 public Driver(Car car)
mycar = car;
所以,关联、聚合、组合只能配合语义,结合上下文才能够判断出来,而只给出一段代码让我们判断是关联,聚合,还是组合关系,则是无法判断的。
比如A类中包含B类的一个引用b,当A类的一个对象消亡时,b这个引用所指向的对象也同时消亡(没有任何一个引用指向它,成了垃圾对象),这种情况叫做组合,反之b所指向的对象还会有另外的引用指向它,这种情况叫聚合。
在实际写代码时组合方式一般会这样写:
A类的构造方法里创建B类的对象,也就是说,当A类的一个对象产生时,B类的对象随之产生,当A类的这个对象消亡时,它所包含的B类的对象也随之消亡。
聚合方式则是这样:
A类的对象在创建时不会立即创建B类的对象,而是等待一个外界的对象传给它
传给它的这个对象不是A类创建的。
现实生活中:
人和人和手,脚是组合关系,因为当人死亡后人的手也就不复存在了。人和他的电脑是聚合关系。 class Hand class Computer 组合: class Person private Hand hand; public Person() hand = new Hand(); 聚合: class Person private Computer computer; public setComputer() computer = new Computer();
以编程方式区分组合和聚合
【中文标题】以编程方式区分组合和聚合【英文标题】:Differentiating Composition and Aggregation programmatically 【发布时间】:2018-10-11 07:21:48 【问题描述】:我正在通过下面的链接来找出组合和聚合之间的区别。
https://www.geeksforgeeks.org/association-composition-aggregation-java/
我能够理解,组合意味着孩子不能独立于父母而存在的关系,而聚合意味着孩子可以独立于父母而存在的关系。但无法理解我如何以编程方式区分它。下面是链接中给出的聚合和组合的示例。在这两种情况下,除了 Student 和 Department 类有一个额外的变量“name”之外,类在结构上是相同的。在组合中,“子不能独立于父”而存在,但是在这里我可以创建一个单独的 Book 对象并在不添加到 Library 的情况下使用它。
聚合
// student class
class Student
String name;
int id ;
String dept;
Student(String name, int id, String dept)
this.name = name;
this.id = id;
this.dept = dept;
/* Department class contains list of student
Objects. It is associated with student
class through its Object(s). */
class Department
String name;
private List<Student> students;
Department(String name, List<Student> students)
this.name = name;
this.students = students;
public List<Student> getStudents()
return students;
作曲
class Book
public String title;
public String author;
Book(String title, String author)
this.title = title;
this.author = author;
// Libary class contains
// list of books.
class Library
// reference to refer to list of books.
private final List<Book> books;
Library (List<Book> books)
this.books = books;
public List<Book> getTotalBooksInLibrary()
return books;
【问题讨论】:
您无法以编程方式区分组合与聚合。差异是相当哲学的。 【参考方案1】:据我所知(也许其他人可以给出更好的答案),您无法仅通过查看 Java 代码来评估关系是聚合还是组合。反之亦然。
首先,您创建一个世界的概念模型。图书馆有书,汽车有***。然后你会想 - 在我工作的背景下,没有图书馆而存在书籍是否有意义,或者没有汽车而存在车轮是否有意义。因此,例如,如果您正在编写赛车游戏,那么您将不会使用汽车之外的***。但是,如果您正在编写一些自动修复应用程序,您将独立于某些特定汽车来处理车轮。
因此,首先您决定是否需要聚合或组合,然后在您的代码中实现它。实现可能是对象Car
具有List<Wheel>
,但仅凭此您无法判断它是组合还是聚合。关键是你根据你的概念模型来解释代码(实现),然后根据它来使用它。
如果是组合的话,使用上可能会有一些限制:
除Car
之外的任何对象都不会持有对Wheel
的引用。
Wheel
甚至可能是私有或包私有类。
如果Car
保存在数据库中,当你删除它时,你也会自动删除它所有的Wheel
s。
但是,如果您决定它的组成,则由您来执行这些限制。
【讨论】:
【参考方案2】:在现实世界中,一本书可以确实独立存在,而不属于图书馆。但是,如果您有一个 LibraryBook
类,其中包含 dateAcquired
和 currentBorrower
之类的字段,该怎么办?使用您的设计,您仍然可以在没有库的情况下创建 LibraryBook 实例。
这就是像 C++ 这样的语言在组合方面可以更加明确的地方:在 C++ 中,对象可以按值保存其部分。在 Java 中,每个对象都由一个指针处理(好吧,Java 人不称它们为指针;他们称它们为引用。)这使得区分组合和聚合变得更加困难。在 Java 中,您需要仔细设计。
例如,我们可以通过Library
的方法使LibraryBook
类只能实例化:
class Library
class LibraryBook
private LibraryBook() /*private constructor prevents independent instantiation*/
LibraryBook createBook(String title, etc...);
此外,如果我们让 LibraryBook 的 mutator 方法只能由 Library 类访问,我们可以确保这本书仍然是其所属图书馆的一部分。
【讨论】:
好的..但是组合可以存在于类及其嵌套类之间,如您的示例所示,因为根据链接中的定义“关联是通过它们的对象建立的两个独立类之间的关系”和组合是协会的一部分以上是关于java 聚合和组合的区别?的主要内容,如果未能解决你的问题,请参考以下文章