我正在尝试理解聚合和组合
假设我有类似下面的内容:
我想用java实现它,下面的实现是否正确?
public class ClassC { private String z; }
public class ClassB {
private String y;
private ClassC classC;
//-----setter and getter for classC
}
public class ClassA {
private String x;
private List<ClassB> classBList;
public ClassA(final List<ClassB> classBList) {
this.classBList=classBList
}
}
另外,如何确保ClassB可以正好拥有1个ClassC?
和ClassA可以有1个或更多ClassB?如箭头所示(如果我正确理解这些符号)。
答案 0 :(得分:1)
我认为可能令人困惑的是构图和聚合之间的区别,因为两者都是“有”关系的样本。 但是,组合比聚合更强,包含对象控制零件对象的整个生命周期。
你可以用最终的方式写它,但它没有达到标记:
public class ClassA {
private String x;
private final List<ClassB> classBList;
public ClassA(String x, List<ClassB> classBList) {
this.classBList=classBList;
this.x = x;
}
}
我认为这样可以更清晰地表达:
public class ClassA{
private String x;
private final List<ClassB> classBList;
public ClassA(String x){
this.x = x;
classBList = new ArrayList<ClassB>(2);
classBList.add(new ClassB(..........));
classBList.add(new ClassB(..........));
}
}
答案 1 :(得分:0)
您可以使用类图作为示例对此进行建模。对于ClassA,像mihaisimi那样:在ClassA的构造函数中实例化ClassB列表。如果要准确确定应该将多少ClassB实例作为给定ClassA实例的一部分,只需将一个整数参数添加到构造函数中,如果它是0,则抛出异常。然后使用作为Add方法的循环计数器传递的值
对于ClassB,将参数添加到其类型为ClassC的构造函数中。所以,这样的事情(java有点生疏,所以随时根据需要纠正我的语法):
public class ClassA
{
public final List<ClassB> classBList;
public ClassA(int y){
this.myClassBList = x;
classBList = new ArrayList<ClassB>(y);
for(int i=0;i<y;i++)
{
classBList.add(new ClassB(new ClassC));
}
}
public class ClassB
{
public ClassC myClassCInstance;
public ClassB(ClassC myClassC)
{
myClassCInstance = myClassC;
}
}
如您所见,这允许您拥有与ClassA实例关联的任意数量的ClassB实例,并根据组合需要将其生命周期与ClassA联系起来。此外,正如您所看到的,您不能向ClassB的任何实例添加多个ClassC实例,并且ClassB的生命周期并不严格地与ClassB相关联。
因此,如何对组合和构造进行建模的基本区别在于:对于组合,在组合对象(具有菱形的构造函数)构造函数中实例化组合对象,并且为了聚合,将聚合对象传递到聚合对象的构造函数中作为参数。
答案 2 :(得分:0)
有很多正确的方法可以实现这样的类图。
但是为了选择正确的实现,首先应确保理解UML中定义的Association,Aggregation和Composition的概念。
我在我的网站上写了一篇关于这个问题的文章:UML Composition vs Aggregation vs Association
简而言之,组合是一种具有实际约束和对发展的影响的关联,而聚合纯粹是协会性质的功能性指示,没有技术影响。