java中的组合与聚合,区别。。。详细点

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java中的组合与聚合,区别。。。详细点相关的知识,希望对你有一定的参考价值。

画出的UML图一样的吗??

聚合就是:表示两个对象之间是整体和部分的弱关系,部分的生命周期可以超越整体。如下:实例化Person,不一定要实例化Telephone。has a
public class Person
private Telephone tel;

private Hand hand = new Hand();
.......

class Telephone

......

组合:组合:表示两个对象之间是整体和部分的强关系,部分的生命周期不能超越整体,或者说不能脱离整体而存在。组合关系的“部分”,是不能在整体之间进行共享的。如人和手的关系:人是整体,手是部分。is a 的关系 。手不能脱离人。
public class hand
......

参考技术A 组成就是强聚合,比如班级和学生间的关系应该是聚合,学生和学号的关系就应该是组成
班级、学生都是有独立意义的对象,但是学号要是没有学生就没什么意义了
组成要求整体和组成部分共存亡,他们的生命期相同,谁也离不开谁。
图上的时候聚合貌似是空心的零菱形,组成是实心的。
参考技术B 聚合是关联关系的一种特例,他体现的是整体与部分 拥有的关系,即has-a的关系,此时整体与部分之间是可以分离的,他们可以具有各自的生命周期,部分可以属于多个整体对象,也可以为多个整体对象共享;比如计算机与CPU,公司与员工的关系;
组合也是关联关系的一种特例,他体现的也是一种contain-a的关系,这种关系比聚合更强,也称为强聚合,他同样体现整体与部分件的关系,但此时整体与部分是不可分的,整体的声明周期结束也就意味着部分的声明周期结束;比如你和你的大脑;
UML图表示不一样

Java中聚合和组合的实现区别

【中文标题】Java中聚合和组合的实现区别【英文标题】:Implementation difference between Aggregation and Composition in Java 【发布时间】:2012-08-06 13:38:43 【问题描述】:

我知道聚合和组合之间的概念差异。有人可以通过示例告诉我它们之间在 Java 中的实现差异吗?

【问题讨论】:

点击此链接,您可能会得到您帖子的答案 [聚合与组合的区别] [1] [1]:***.com/a/1468285/1353243 Aggregation versus Composition的可能重复 另见c-sharp-code-for-association-aggregation-composition 当我们在对象之间有任何关系时,称为关联。聚合和组合都是关联的特殊形式。组合再次是聚合的特殊形式。 javabench.in/2011/08/difference-between-association.html 你可以找到更多答案here 【参考方案1】:

作曲

final class Car 

  private final Engine engine;

  Car(EngineSpecs specs) 
    engine = new Engine(specs);
  

  void move() 
    engine.work();
  

聚合

final class Car 

  private Engine engine;

  void setEngine(Engine engine) 
    this.engine = engine;
  

  void move() 
    if (engine != null)
      engine.work();
  

在组合的情况下,Engine完全被Car封装。外界无法获得对 Engine 的引用。引擎与汽车一起生死存亡。通过聚合,Car 也通过 Engine 执行其功能,但 Engine 并不总是 Car 的内部部分。引擎可能会被交换,甚至完全移除。不仅如此,外界仍然可以对 Engine 有一个引用,并且不管它是否在 Car 中,都可以对其进行修改。

【讨论】:

很好的例子!它还将组合显示为强关联(没有引擎的汽车毫无意义)和聚合作为弱关联(没有引擎的汽车完全有意义,它甚至不需要在其构造函数中)。使用哪一个?取决于上下文。 @Anand 你在聚合中给出的例子不是这个依赖例子吗?依赖是一种较弱的关系形式,用代码术语表示一个类通过参数或返回类型使用另一个类。 @Anand:你能解释一下你为什么说:在组合的情况下,外界无法获得对引擎的引用,而通过聚合,外界可以得到对引擎的引用引擎?您能否在代码示例中展示外部世界如何可以或不能参考引擎?谢谢 这不是一个正确的例子。外部世界可以访问内部对象,但它的身份始终与外部对象相关联,而在聚合中,即使没有汽车,内部对象也可能独立存在。在这种情况下,即使没有汽车,仍然可以使用 new Engine(EngineSpecs) 调用创建引擎。实现组合的方法是将Engine创建为一个内部类,这样引擎的对象总是参照一个Car Object来创建 @mickeymoon 很棒。你能给我们举一个更好的例子吗?【参考方案2】:

我会使用一个很好的 UML 示例。

以一所拥有 1 到 20 个不同系且每个系有 1 到 5 位教授的大学为例。 大学和它的部门之间有一个组成联系。 一个系和它的教授之间有一个聚合链接。

组合只是一个强大的聚合,如果大学被摧毁,那么部门也应该被摧毁。但我们不应该杀死教授,即使他们各自的部门消失了。

在java中:

public class University 

     private List<Department> departments;

     public void destroy()
         //it's composition, when I destroy a university I also destroy the departments. they cant live outside my university instance
         if(departments!=null)
             for(Department d : departments) d.destroy();
         departments.clean();
         departments = null;
     


public class Department 

     private List<Professor> professors;
     private University university;

     Department(University univ)
         this.university = univ;
         //check here univ not null throw whatever depending on your needs
     

     public void destroy()
         //It's aggregation here, we just tell the professor they are fired but they can still keep living
         for(Professor p:professors)
             p.fire(this);
         professors.clean();
         professors = null;
     


public class Professor 

     private String name;
     private List<Department> attachedDepartments;

     public void destroy()

     

     public void fire(Department d)
         attachedDepartments.remove(d);
     

围绕这个。

编辑:根据要求提供示例

public class Test

    public static void main(String[] args)
    
        University university = new University();
        //the department only exists in the university
        Department dep = university.createDepartment();
        // the professor exists outside the university
        Professor prof = new Professor("Raoul");
        System.out.println(university.toString());
        System.out.println(prof.toString());

        dep.assign(prof);
        System.out.println(university.toString());
        System.out.println(prof.toString());
        dep.destroy();

        System.out.println(university.toString());
        System.out.println(prof.toString());

    



大学课堂

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

public class University 

    private List<Department> departments = new ArrayList<>();

    public Department createDepartment() 
        final Department dep = new Department(this, "Math");
        departments.add(dep);
        return dep;
    

    public void destroy() 
        System.out.println("Destroying university");
        //it's composition, when I destroy a university I also destroy the departments. they cant live outside my university instance
        if (departments != null)
            departments.forEach(Department::destroy);
        departments = null;
    

    @Override
    public String toString() 
        return "University\n" +
                "departments=\n" + departments.stream().map(Department::toString).collect(Collectors.joining("\n")) +
                "\n";
    

部门类

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

public class Department 

    private final String name;
    private List<Professor> professors = new ArrayList<>();
    private final University university;

    public Department(University univ, String name) 
        this.university = univ;
        this.name = name;
        //check here univ not null throw whatever depending on your needs
    

    public void assign(Professor p) 
        //maybe use a Set here
        System.out.println("Department hiring " + p.getName());
        professors.add(p);
        p.join(this);
    

    public void fire(Professor p) 
        //maybe use a Set here
        System.out.println("Department firing " + p.getName());
        professors.remove(p);
        p.quit(this);
    

    public void destroy() 
        //It's aggregation here, we just tell the professor they are fired but they can still keep living
        System.out.println("Destroying department");
        professors.forEach(professor -> professor.quit(this));
        professors = null;
    

    @Override
    public String toString() 
        return professors == null
                ? "Department " + name + " doesn't exists anymore"
                : "Department " + name + "\n" +
                "professors=" + professors.stream().map(Professor::toString).collect(Collectors.joining("\n")) +
                "\n";
    

教授班

import java.util.ArrayList;
import java.util.List;

public class Professor 

    private final String name;
    private final List<Department> attachedDepartments = new ArrayList<>();

    public Professor(String name) 
        this.name = name;
    

    public void destroy() 

    

    public void join(Department d) 
        attachedDepartments.add(d);
    

    public void quit(Department d) 
        attachedDepartments.remove(d);
    

    public String getName() 
        return name;
    

    @Override
    public String toString() 
        return "Professor " + name + " working for " + attachedDepartments.size() + " department(s)\n";
    

实施是有争议的,因为它取决于您需要如何处理创建、雇用删除等。与 OP 无关

【讨论】:

我希望我不会得到任何关于未初始化列表和没有构造函数的评论。我写得很快,缺少的部分是常识,但如果被问到我会完成解决方案 谢谢!你的例子很清楚。但我无法理解您的代码说明。你能告诉我两者之间的基本实现区别吗?如果我必须实现聚合或组合,我应该使用 Java 中的哪些概念? 如果你谈论类,它的实现是完全相同的,但是组合应该反映在你管理实例的方式上,就像我在编辑中一样 TecHunter,我正在寻找这个例子。您是否还可以扩展用于在大学示例中演示关联的 java 代码。该示例应如何在 main() 方法中运行。 (可以显示创建大学和删除教授的场景)。请帮忙 @deepakl.2000 有很多方法可以做到这一点。你应该定义哪个类有权力。可能是教授加入大学,然后是一对多系,也可能是大学聘请教授,然后要求该系注册。一切都是为了满足您的需求。【参考方案3】:

一个简单的作曲程序

public class Person 
    private double salary;
    private String name;
    private Birthday bday;

    public Person(int y,int m,int d,String name)
        bday=new Birthday(y, m, d);
        this.name=name;
    


    public double getSalary() 
        return salary;
    

    public String getName() 
        return name;
    

    public Birthday getBday() 
        return bday;
    

    ///////////////////////////////inner class///////////////////////
    private class Birthday
        int year,month,day;

        public Birthday(int y,int m,int d)
            year=y;
            month=m;
            day=d;
        

        public String toString()
           return String.format("%s-%s-%s", year,month,day);

        
    

    //////////////////////////////////////////////////////////////////


public class CompositionTst 

    public static void main(String[] args) 
        // TODO code application logic here
        Person person=new Person(2001, 11, 29, "Thilina");
        System.out.println("Name : "+person.getName());
        System.out.println("Birthday : "+person.getBday());

        //The below object cannot be created. A bithday cannot exixts without a Person 
        //Birthday bday=new Birthday(1988,11,10);

    

【讨论】:

您能否为关联和聚合添加有效的 Java 代码,并解释您在组合中解释的所有场景? 1. 关联场景如果被删除? 2. 删除父对象时聚合中的场景?【参考方案4】:

简单来说:

组合和聚合都是关联。 组合 -> 强 Has-A 关系 聚合 -> 弱 Has-A 关系。

【讨论】:

【参考方案5】:

下面给出的网址中有一个很好的解释。

http://www.codeproject.com/Articles/330447/Understanding-Association-Aggregation-and-Composit

请检查!!!

【讨论】:

嗨 Rahul,虽然此链接可能会回答问题,但最好在此处包含答案的基本部分并提供链接以供参考。如果链接页面发生更改,仅链接答案可能会失效。请看这里:Why and how are some answers deleted?【参考方案6】:

首先我们必须谈谈AggregationComposition 在同一页面上的实际区别。

聚合是一种关联,关联实体可以独立于关联而存在。例如,一个人可能与一个组织相关联,但他/她可能在系统中独立存在。

组合是指其中一个关联实体与另一个密切相关并且没有另一个存在就不能存在的情况。事实上,该实体的身份总是与另一个对象的身份相关联。例如,汽车的***。

现在,聚合可以简单地通过将一个实体的属性保存在另一个实体中来实现,如下所示:

class Person 
    Organisation worksFor;


class Organisation 
    String name;


class Main 
    public static void main(String args[]) 

        //Create Person object independently
        Person p = new Person();

        //Create the Organisation independently
        Organisation o = new Organisation();
        o.name = "XYZ Corporation";

        /*
          At this point both person and organisation 
          exist without any association  
        */
        p.worksFor = o;

    

对于组合而言,依赖对象必须始终以其关联对象的身份创建。您也可以使用内部类。

class Car 
    class Wheel 
        Car associatedWith;
    


class Main 
    public static void main() 
        //Create Car object independently
        Car car = new Car();

        //Cannot create Wheel instance independently
        //need a reference of a Car for the same.
        Car.Wheel wheel = car.new Wheel();
    

请注意,根据应用场景,相同的用例可能属于聚合/组合。例如,如果您正在为在某个组织中工作的人员开发应用程序,并且必须在注册时引用组织,则人员-组织案例可能会变成组合。同样,如果您要维护汽车零件的库存,则可以聚合 Car-Wheel 关系。

【讨论】:

【参考方案7】:

不同之处在于,任何组合都是聚合,反之则不然。

让我们设定条款。 Aggregation 是 UML 标准中的一个元术语,表示组合和共享聚合,简称为 shared。它经常被错误地命名为“聚合”。这很糟糕,因为组合也是一种聚合。据我了解,您的意思是“共享”。

UML 标准的进一步说明:

composite - 表示属性是复合聚合的, 即,复合对象对存在和 组合对象(部分)的存储。

因此,大学与大教堂协会是一个组合,因为大学不存在大教堂(恕我直言)

共享聚合的精确语义因应用领域和 建模师。

即,如果您只遵循您或其他人的某些原则,则所有其他关联都可以绘制为共享聚合。也看here。

【讨论】:

【参考方案8】:

聚合与组合

聚合意味着孩子可以独立于父母而存在的关系。比如Bank and Employee,删除Bank,Employee仍然存在。

组合意味着孩子不能独立于父母而存在的关系。示例:人与心,心与人是分不开的。

聚合关系是“has-a”组合是“part-of”关系。

Composition 是强关联,而 Aggregation 是弱关联。

【讨论】:

Bank 和 Employee 应该是组合关系。因为如果你删除银行,员工就不会继续存在。我们必须根据系统而不是现实世界来思考。是的,这个人继续存在。但如果一家银行完全破产,员工就会被解雇——你不能成为一家不存在的银行的员工。一个更好的例子是 BankBranch 和 Customer。如果您删除银行的分行(它在下面),客户仍然存在并且可以选择被分配到不同的分行。在移植/实验室的情况下,器官可以与人类分开存在。【参考方案9】:

这两种类型当然都是关联,并没有真正严格地映射到这样的语言元素。区别在于目的、上下文以及系统的建模方式。

作为一个实际示例,比较具有相似实体的两种不同类型的系统:

主要跟踪汽车及其所有者等的汽车注册系统。这里我们对作为一个单独实体的引擎不感兴趣,但我们可能仍然有与引擎相关的属性,例如功率和燃料类型。这里的引擎可能是汽车实体的复合部分。

汽车维修店管理系统,用于管理汽车零件、维修汽车和更换零件,可能是整个发动机。在这里,我们甚至可能有发动机库存,需要单独跟踪它们和其他部件,并且独立于汽车。在这里,引擎可能是汽车实体的聚合部分。

您如何用您的语言实现这一点是次要问题,因为在那个级别上,诸如可读性之类的事情要重要得多。

【讨论】:

以上是关于java中的组合与聚合,区别。。。详细点的主要内容,如果未能解决你的问题,请参考以下文章

java中的组合和聚合有啥区别? [复制]

架构漫谈:UML中几种类间关系:继承实现依赖关联聚合组合的联系与区别

java基础--继承实现依赖关联聚合组合的联系与区别

java 里 getSelectedItem与getSelectedIndex的区别(拜托大哥大姐说详细点)

H3C端口聚合中的 both ingress区别在哪,要详细的,谢谢

什么是java聚合工程