Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Oop 关联、聚合和组合之间的区别是什么?_Oop_Uml_Associations_Aggregation_Composition - Fatal编程技术网

Oop 关联、聚合和组合之间的区别是什么?

Oop 关联、聚合和组合之间的区别是什么?,oop,uml,associations,aggregation,composition,Oop,Uml,Associations,Aggregation,Composition,关联、聚合和组合之间的区别是什么? 请从实施的角度进行解释。我认为此链接可以帮助您完成以下任务: 为了理解这些术语,我在早期编程时记得一个例子: 如果您有一个“棋盘”对象,其中包含组成为的“盒子”对象,因为如果删除了“棋盘”,盒子就没有理由再存在了 如果您有一个具有“颜色”对象的“正方形”对象,并且该正方形被删除,“颜色”对象可能仍然存在,即聚合 它们都是关联,主要区别是概念上的正如其他人所说,关联是对象之间的关系,聚合和组合是关联的类型 从实现的角度来看,聚合是通过引用类成员来获得的。例如,如

关联、聚合和组合之间的区别是什么?
请从实施的角度进行解释。

我认为此链接可以帮助您完成以下任务:

为了理解这些术语,我在早期编程时记得一个例子:

如果您有一个“棋盘”对象,其中包含组成为的“盒子”对象,因为如果删除了“棋盘”,盒子就没有理由再存在了

如果您有一个具有“颜色”对象的“正方形”对象,并且该正方形被删除,“颜色”对象可能仍然存在,即聚合


它们都是关联,主要区别是概念上的

正如其他人所说,关联是对象之间的关系,聚合和组合是关联的类型

从实现的角度来看,聚合是通过引用类成员来获得的。例如,如果类A聚合了类B的一个对象,您将有如下内容(在C++中):

聚合的语义是,当一个对象A被销毁时,它存储的对象B仍然存在。当使用合成时,通常通过按值存储成员来增强关系:

class A {
    B element;
};
在这里,当A对象被销毁时,它包含的B对象也将被销毁。实现这一点的最简单方法是按值存储成员,但也可以使用一些智能指针,或在析构函数中删除成员:

class A {
    std::auto_ptr<B> element;
};

class A {
    B * element;

    ~A() {
        delete B;
    }
};
A类{
std::自动ptr元件;
};
甲级{
B*要素;
~A(){
删除B;
}
};
重要的一点是,在合成中,容器对象拥有所包含的对象,而在聚合中,它通过以下方式引用它。

关联表示一个实例向另一个实例发送消息的能力。这通常是通过指针或引用实例变量实现的,尽管它也可以作为方法参数或局部变量的创建来实现

//[Example:]

//|A|----------->|B|

class A
{
  private:
    B* itsB;
};
聚合[…]是典型的整体/部分关系。这与关联完全相同,只是实例不能具有循环聚合关系(即一个部分不能包含其整体)

/[示例:]
//|节点|---------------->|节点|
类节点
{
私人:
向量及其节点;
};
这是聚合的事实意味着节点的实例不能形成一个循环。因此,这是一个节点树,而不是一个节点图

合成[…]与聚合完全相同,只是“部分”的寿命由“整体”控制。此控件可以是直接的或可传递的。也就是说,“整体”可能直接负责创建或销毁“部分”,也可能接受已创建的部分,然后将其传递给其他承担责任的整体

//[Example:]

//|Car|<#>-------->|Carburetor|

class Car
{
  public:
    virtual ~Car() {delete itsCarb;}
  private:
    Carburetor* itsCarb
};
/[示例:]
//|汽车化油器|
班车
{
公众:
virtual~Car(){delete itsCarb;}
私人:
化油器
};

对于两个对象,
Foo
Bar
可以定义关系


关联-我与一个对象有关系<代码>Foo使用

public class Foo { 
    void Baz(Bar bar) {
    } 
};

合成-我拥有一个对象,并对其生命周期负责。当
Foo
死亡时,
Bar

public class Foo {
    private Bar bar = new Bar(); 
}
聚合-我有一个从别人那里借来的对象。当
Foo
死亡时,
Bar
可以继续生存

public class Foo { 
    private Bar bar; 
    Foo(Bar bar) { 
       this.bar = bar; 
    }
}

我知道这个问题被标记为C#,但这里的概念非常通用。因此,我将在这里提供我的观点(从java的角度来看,我有点偏颇,我比较舒服)

当我们想到面向对象的本质时,我们总是想到对象、类(对象蓝图)以及它们之间的关系。对象通过方法相互关联和交互。换句话说,一个类的对象可以使用另一个类的对象提供的服务/方法。这种关系称为关联。

聚合和合成是关联的子集意味着它们是关联的特定案例

  • 在聚合和合成中,一个类的对象“拥有”另一个类的对象
  • 但有一个微妙的区别。在合成中由其所属阶级的客体所拥有的阶级客体不能独立生存(也称为“死亡关系”)。它将始终作为其所属对象的一部分存在,在聚合中,从属对象是独立的,即使所属类的对象已死亡,也可以存在
  • 因此,在组合中,如果拥有的对象被垃圾收集,那么拥有的对象也将被垃圾收集,而在聚合中则不是这样
困惑

<强>构图示例< /强>:考虑一个汽车和一个引擎非常具体的例子(这意味着它不能用于任何其他汽车)。汽车特定发动机等级之间的这种关系称为组合。没有SpecificEngine类的对象,Car类的对象就不可能存在,没有Car类,SpecificEngine的对象就没有意义。简单地说,汽车类仅“拥有”特定的发动机类

<强>聚合示例:现在考虑类< St>Cuth/Stand >类<强>车轮< /强>。汽车需要一个轮子来运转。这意味着汽车对象拥有车轮对象,但如果没有汽车对象,我们不能说车轮对象没有意义。它可以很好地用于自行车、卡车或不同的汽车

public class Foo { private Bar bar = new Bar(); }
public class Foo { 
    private Bar bar; 
    Foo(Bar bar) { 
       this.bar = bar; 
    }
}
public class EnrollmentService {
    public void enroll(Student s, Course c){}
}
public class Order {
    private Customer customer
}
public class PlayList {
    private List<Song> songs;
}
public class Computer {
    private Monitor monitor;
}
public class Apartment{
    private Room bedroom;
    public Apartment() {
       bedroom = new Room();
    }
}
final class Car {    
  private final Engine engine;

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

  void move() {
    engine.work();
  }
}
class Room < ActiveRecord::Base
  belongs_to :house, required: true
end
class Room < ApplicationRecord
  belongs_to :house
end
class Product < ApplicationRecord
  belongs_to :category, optional: true
end
#include <iostream>
using namespace std;
/********************** Engine Class ******************/
class Engine
{
    int nEngineNumber;
    public:
    Engine(int nEngineNo);
    ~Engine(void);
};
Engine::Engine(int nEngineNo)
{
    cout<<" Engine :: Constructor " <<endl;
}
Engine::~Engine(void)
{
    cout<<" Engine :: Destructor " <<endl;
}
/********************** Car Class ******************/
class Car
{
    int nCarColorNumber;
    int nCarModelNumber;
    Engine objEngine;
    public:
    Car (int, int,int);
    ~Car(void);
};
Car::Car(int nModelNo,int nColorNo, int nEngineNo):
nCarModelNumber(nModelNo),nCarColorNumber(nColorNo),objEngine(nEngineNo)
{
    cout<<" Car :: Constructor " <<endl;
}
Car::~Car(void)
{
    cout<<" Car :: Destructor " <<endl;
    Car
    Engine
    Figure 1 : Composition
}
/********************** Bus Class ******************/
class Bus
{
    int nBusColorNumber;
    int nBusModelNumber;
    Engine* ptrEngine;
    public:
    Bus(int,int,int);
    ~Bus(void);
};
Bus::Bus(int nModelNo,int nColorNo, int nEngineNo):
nBusModelNumber(nModelNo),nBusColorNumber(nColorNo)
{
    ptrEngine = new Engine(nEngineNo);
    cout<<" Bus :: Constructor " <<endl;
}
Bus::~Bus(void)
{
    cout<<" Bus :: Destructor " <<endl;
    delete ptrEngine;
}
/********************** Main Function ******************/
int main()
{
    freopen ("InstallationDump.Log", "w", stdout);
    cout<<"--------------- Start Of Program --------------------"<<endl;
    // Composition using simple Engine in a car object
    {
        cout<<"------------- Inside Car Block ------------------"<<endl;
        Car objCar (1, 2,3);
    }
    cout<<"------------- Out of Car Block ------------------"<<endl;
    // Composition using pointer of Engine in a Bus object
    {
        cout<<"------------- Inside Bus Block ------------------"<<endl;
        Bus objBus(11, 22,33);
    }
    cout<<"------------- Out of Bus Block ------------------"<<endl;
    cout<<"--------------- End Of Program --------------------"<<endl;
    fclose (stdout);
}
--------------- Start Of Program --------------------
------------- Inside Car Block ------------------
Engine :: Constructor
Car :: Constructor
Car :: Destructor
Engine :: Destructor
------------- Out of Car Block ------------------
------------- Inside Bus Block ------------------
Engine :: Constructor
Bus :: Constructor
Bus :: Destructor
Engine :: Destructor
------------- Out of Bus Block ------------------
--------------- End Of Program --------------------
#include <iostream>
#include <string>
using namespace std;
/********************** Teacher Class ******************/
class Teacher
{
    private:
    string m_strName;
    public:
    Teacher(string strName);
    ~Teacher(void);
    string GetName();
};
Teacher::Teacher(string strName) : m_strName(strName)
{
    cout<<" Teacher :: Constructor --- Teacher Name :: "<<m_strName<<endl;
}
Teacher::~Teacher(void)
{
    cout<<" Teacher :: Destructor --- Teacher Name :: "<<m_strName<<endl;
}
string Teacher::GetName()
{
    return m_strName;
}
/********************** Department Class ******************/
class Department
{
    private:
    Teacher *m_pcTeacher;
    Teacher& m_refTeacher;
    public:
    Department(Teacher *pcTeacher, Teacher& objTeacher);
    ~Department(void);
};
Department::Department(Teacher *pcTeacher, Teacher& objTeacher)
: m_pcTeacher(pcTeacher), m_refTeacher(objTeacher)
{
    cout<<" Department :: Constructor " <<endl;
}
Department::~Department(void)
{
    cout<<" Department :: Destructor " <<endl;
}
/********************** Main Function ******************/
int main()
{
    freopen ("InstallationDump.Log", "w", stdout);
    cout<<"--------------- Start Of Program --------------------"<<endl;
    {
        // Create a teacher outside the scope of the Department
        Teacher objTeacher("Reference Teacher");
        Teacher *pTeacher = new Teacher("Pointer Teacher"); // create a teacher
        {
            cout<<"------------- Inside Block ------------------"<<endl;
            // Create a department and use the constructor parameter to pass the teacher to it.
            Department cDept(pTeacher,objTeacher);
            Department
            Teacher
            Figure 2: Aggregation
        } // cDept goes out of scope here and is destroyed
        cout<<"------------- Out of Block ------------------"<<endl;
        // pTeacher still exists here because cDept did not destroy it
        delete pTeacher;
    }
    cout<<"--------------- End Of Program --------------------"<<endl;
    fclose (stdout);
}
--------------- Start Of Program --------------------
Teacher :: Constructor --- Teacher Name :: Reference Teacher
Teacher :: Constructor --- Teacher Name :: Pointer Teacher
------------- Inside Block ------------------
Department :: Constructor
Department :: Destructor
------------- Out of Block ------------------
Teacher :: Destructor --- Teacher Name :: Pointer Teacher
Teacher :: Destructor --- Teacher Name :: Reference Teacher
--------------- End Of Program --------------------
    Simple rules:
    A "owns" B = Composition : B has no meaning or purpose in the system 
    without A
    A "uses" B = Aggregation : B exists independently (conceptually) from A
    A "belongs/Have" B= Association; And B exists just have a relation
    Example 1:

    A Company is an aggregation of Employees.
    A Company is a composition of Accounts. When a Company ceases to do 
    business its Accounts cease to exist but its People continue to exist. 
    Employees have association relationship with each other.

    Example 2: (very simplified)
    A Text Editor owns a Buffer (composition). A Text Editor uses a File 
    (aggregation). When the Text Editor is closed,
    the Buffer is destroyed but the File itself is not destroyed.