关联、聚合和组合之间的区别是什么? 请从实施的角度加以说明。
当前回答
组合(如果你删除“整体”,“部分”也会自动删除-“所有权”)
在新类中创建现有类的对象。这称为组合,因为新类是由现有类的对象组成的。 通常使用普通成员变量。 如果组合类自动处理负责创建/销毁子类的分配/回收,则可以使用指针值。
c++中的复合
#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 --------------------
聚合(如果你删除“整体”,“部分”可以存在-“无所有权”)
聚合是一种特定类型的组合,其中不暗示复杂对象和子对象之间的所有权。当一个聚合被销毁时,子对象不会被销毁。 通常使用指针变量/引用变量指向在聚合类作用域之外的对象 可以使用指向在聚合类范围之外的对象的引用值吗 不负责创建/销毁子类
c++中的聚合代码
#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 --------------------
其他回答
组合(如果你删除“整体”,“部分”也会自动删除-“所有权”)
在新类中创建现有类的对象。这称为组合,因为新类是由现有类的对象组成的。 通常使用普通成员变量。 如果组合类自动处理负责创建/销毁子类的分配/回收,则可以使用指针值。
c++中的复合
#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 --------------------
聚合(如果你删除“整体”,“部分”可以存在-“无所有权”)
聚合是一种特定类型的组合,其中不暗示复杂对象和子对象之间的所有权。当一个聚合被销毁时,子对象不会被销毁。 通常使用指针变量/引用变量指向在聚合类作用域之外的对象 可以使用指向在聚合类范围之外的对象的引用值吗 不负责创建/销毁子类
c++中的聚合代码
#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 --------------------
成分: 一旦你摧毁了一个对象(学校),另一个与之绑定的对象(教室)也会被摧毁。两者都不能独立存在。
聚合: 这与上面的(Composition)关联完全相反,在上面的关联中,一旦你杀死了一个对象(Company),绑定到它的另一个对象(Employees)就可以独立存在。
协会。 组合和聚合是关联的两种形式。
https://www.linkedin.com/pulse/types-relationships-object-oriented-programming-oop-sarah-el-dawody/
Composition:是一种“part-of”关系。
例如,“发动机是汽车的一部分”,“心脏是身体的一部分”。
关联:是“has-a”类型的关系
例如,假设我们有两个类,那么这两个类被称为“has-a”关系,如果这两个实体为了某些工作而共享彼此的对象,同时它们可以不依赖彼此而存在,或者它们都有自己的生命期。
上面的示例显示了一种关联关系,因为Employee类和Manager类都使用彼此的对象,并且都有各自独立的生命周期。
聚合:是基于“has-a”关系,是一种特殊的关联形式
例如,“学生”和“地址”。每个学生必须有一个地址,所以学生类和地址类之间的关系将是“Has-A”类型的关系,反之亦然。
联想是关系的广义概念。它包括组合和聚合。
组合(混合)是一种将简单对象或数据类型包装成单个单元的方法。组合是许多基本数据结构的关键构建块
聚合(将许多事物形成一个集群)不同于普通的组合,因为它不意味着所有权。在组合中,当拥有的对象被销毁时,包含的对象也被销毁。总的来说,这并不一定正确。
记住区别的技巧:
“有一个”:聚合 “局部”:comPOsitoin “是一个”:继承
context | Aggregation | Composition |
---|---|---|
Life time | objects have their own lifetime and there is no owner | controlled by whole or parent that owns it |
Scope | parent objects and child objects are independent | parent object also means the death of its children. |
Relationship | Has-a | Part-of |
Strength | weak relationship | strong relationship. |
Real-life example | Car and Driver | Car and wheels |
现在让我们观察下面的图像
类比:
合成:下图是图像合成,即使用单独的图像合成一张图像。
聚合:图像在单一位置的集合
例如,A大学有多个系,每个系都有一些教授。如果大学关闭,这些部门将不复存在,但这些部门的教授将继续存在。因此,一所大学可以被看作是一个系的组成部分,而系则是教授的集合。此外,教授可以在一个以上的部门工作,但一个部门不能属于一所以上的大学。
这些答案的问题在于,它们只说了一半:它们解释了聚合和组合是关联的形式,但没有说一个关联是否可能不是这两种形式。
基于对SO和一些UML文档的一些简要阅读,我收集到类关联有4种主要的具体形式:
A是由A组成的;没有A, B就不存在,就像家里的房间一样 聚合:A有A B;B可以没有A而存在,就像教室里的学生一样 依赖:A使用B;A和B之间没有生命周期依赖关系,比如方法调用参数、返回值或方法调用期间创建的临时对象 泛化:A是A
当两个实体之间的关系不是其中之一时,它可以被称为一般意义上的“关联”,并以其他方式进一步描述(注意,原型等)。
我的猜测是,“通用关联”主要用于两种情况:
when the specifics of a relationship are still being worked out; such relationship in a diagram should be converted as soon as possible to what it actually is/will be (one of the other 4). when a relationship doesn't match any of those 4 predetermined by UML; the "generic" association still gives you a way of representing a relationship that is "not one of the other ones", so that you aren't stuck using an incorrect relationship with a note "this is not actually aggregation, it's just that UML doesn't have any other symbol we could use"
推荐文章
- 是什么导致这个ActiveRecord::ReadOnlyRecord错误?
- 在Java中使用“final”修饰符
- Rails:dependent =>:destroy VS:dependent =>:delete_all
- 我怎么知道什么时候创建一个接口?
- 构造函数vs工厂方法
- 在PHP5中创建单例设计模式
- 什么是依赖倒置原则?为什么它很重要?
- 从Java项目生成UML类图
- 为什么在Python方法中需要显式地有“self”参数?
- js:将一个组件包装成另一个组件
- 如何在方法中访问“静态”类变量?
- 为什么c#不提供c++风格的'friend'关键字?
- String, StringBuffer和StringBuilder
- 显示所有Elasticsearch聚合结果/桶,而不仅仅是10个
- 存储库和服务层的区别?