在OOP中,组合(由UML中的填充菱形表示)与类之间的关联(由UML中的空菱形表示)之间的区别是什么。我有点困惑。什么是聚合?我可以有一个令人信服的现实世界的例子吗?
答案 0 :(得分:35)
<强>组合物强>
想象一下,一个软件公司由不同的业务单位(或部门)组成,如Storage BU,Networking BU。汽车BU。这些业务单位的生命周期由组织的生命周期决定。换句话说,没有公司,这些业务单位不能独立存在。这是组成。 (即公司是业务部门的组成部分)
<强> ASSOCIATION 强>
软件公司可能有外部膳食供应商为员工提供食物。这些餐饮服务商不是公司的一部分。但是,他们与公司有关。即使我们的软件公司关闭,餐饮服务也可以存在。他们可能会为另一家公司服因此,餐饮者的生命周期不受软件公司的生命周期的支配。这是典型的协会
<强>聚集强>
考虑一个汽车制造单位。我们可以将Car视为整体实体,将Car Wheel视为汽车的一部分。 (此时,它可能看起来像组合物。保持开启)轮子可以提前几周创建,并且它可以在装配期间放置在汽车上之前坐在仓库中。在这个例子中,Wheel类的实例显然独立于Car类的实例。 因此,与组合不同,在聚合中,所涉及的对象的生命周期不是紧密耦合的。
答案 1 :(得分:17)
这里举几个例子:
我是公司的员工,因此我与该公司有联系。我不是它的一部分,也不构成它,但与此有关。
我是由器官组成的,除非被移植,否则会死于我。这是组合,它是对象之间非常强大的绑定。基本上,对象由其他对象组成。动词说明了一切。
还有另一种不那么受约束的组合,称为聚合。聚合是指对象由其他对象组成的时间,但它们的生命周期不一定是并列的。使用极端的例子,乐高玩具是零件的集合。即使玩具可以拆卸,它的部件也可以重新组合成一个不同的玩具。
答案 2 :(得分:11)
拥有和使用。
组合:具有引用的对象拥有所引用的对象,并且负责其“生命周期”,它的破坏(并且通常是创建,尽管它可以被传入)。也称为 has-a 关系。
关联:引用的对象使用引用的对象,可能不是独占用户,并且不对其引用的对象的生命周期负责。也称为使用-a 关系。
OP评论:
你能提供一个真实世界的例子吗?另外,什么是聚合? - 马克
聚合:一个从整体到部分的关联,不能是循环的。
示例:
组成:汽车有一个引擎,一个人有一个地址。基本上,必须有,控制一生。
关联:汽车有一个驱动程序,一些类实例有一个错误日志。终身不受控制,可以共享。
聚合:DOM(文档对象模型,即构成HTML元素树的对象)节点具有一个(一组)子节点。节点是顶级(好,更高)级别;它“包含”它的孩子,它们不包含它。
答案 3 :(得分:3)
我认为基于代码的示例可以帮助说明上述响应给出的概念。
import java.util.ArrayList;
public final class AssoCia
{
public static void main( String args[] )
{
B b = new B();
ArrayList<C> cs = new ArrayList();
A a = new A( b, cs );
a.addC( new C() );
a.addC( new C() );
a.addC( new C() );
a.listC();
}
}
class A
{
// Association -
// this instance has a object of other class
// as a member of the class.
private B b;
// Association/Aggregation -
// this instance has a collection of objects
// of other class and this collection is a
// member of this class
private ArrayList<C> cs;
private D d;
public A(B b, ArrayList<C> cs)
{
// Association
this.b = b;
// Association/Aggregation
this.cs = cs;
// Association/Composition -
// this instance is responsible for creating
// the instance of the object of the
// other class. Therefore, when this instance
// is liberated from the memory, the object of
// the other class is liberated, too.
this.d = new D();
}
// Dependency -
// only this method needs the object
// of the other class.
public void addC( C c )
{
cs.add( c );
}
public void listC()
{
for ( C c : cs )
{
System.out.println( c );
}
}
}
class B {}
class C {}
class D {}
答案 4 :(得分:1)
通常,组合意味着包含对象的生命周期以容器的生命周期为界,而关联是对可能独立存在的对象的引用。
然而,这只是我观察到的做法。我讨厌承认这一点,但是在我的有趣的事情列表中,通过UML2规范并不高!
答案 5 :(得分:1)
独立存在。
发票由订单项组成。
什么是不在发票上的订单项?这是 - 好吧 - 没什么。它不能独立存在。
另一方面,发票与客户相关联。
客户独立存在,有或没有发票。
如果这两件事情是独立存在的,那么它们可能是相关联的。
如果有一件事不能独立存在,那么它就是作文的一部分。
答案 6 :(得分:1)
组合是一种比聚合更严格的关系。构图意味着某些东西与其他东西如此密切相关,以至于它们基本上不能独立存在,或者如果它们可以,它们就生活在不同的环境中。
真实世界的例子:你定义一个GUI窗口,然后是一个文本字段,在那里写东西。 在定义GUI的类和定义文本字段的类之间有组合。它们共同构成了一个可以单独看作实体的小部件。假设您删除了窗口,并删除了文本字段。
聚合是不同的,因为两个实体之间的链接是临时的,不稳定的,偶尔的。一个现实世界的例子。假设您有一个包含多个数据实例的对象数据库。现在,您运行一些过滤器来收集服从给定标准的数据实例,并将生成的实例推送到图形列表中,以便用户可以看到它们。当图形小部件接收到对象时,它可以形成这些实体的聚合,并呈现它们。如果用户使用图形列表关闭窗口,并且后者被删除,则不应删除数据对象。也许它们会显示在其他地方,或者你仍然需要它们。
此外,通常,在创建时定义构图。而是在对象生存期中稍后定义聚合。
答案 7 :(得分:0)
组合意味着实体状态的一部分被另一种类型封装,但它实际上是实体状态的一部分。例如,您可能具有地址类型和包含地址的员工实体类型。
关联意味着实体类型与另一个实体类型相关联,但关联实体概念上不是实体状态的一部分。例如,员工可能与公司关联。