我真的很难理解“组合和聚合”。在下面的代码中,我想知道以下哪个汽车实例使用组合逻辑或聚合逻辑。
public class Engine {
public Engine() {
}
}
public class Car1 {
public final Engine engine;
public Car1() {
engine = new Engine();
}
}
class Car2{
public Engine engine;
public Car2(Engine engine) {
this.engine = engine;
}
}
class Car3{
public final Engine engine;
public Car3(Engine engine) {
this.engine = engine;
}
}
class Car4{
Engine engine;
public Car4(){
this.engine = new Engine();
}
}
class Main{
public static void main(String[] args) {
Engine engine = new Engine();
Car1 car1 = new Car1();
Car2 car2_1 = new Car2(new Engine());
Car2 car2_2 = new Car2(engine);
Car3 car3_1 = new Car3(new Engine());
Car3 car3_2 = new Car3(engine);
Car4 car4_1 = new Car4();
}
}
据我说,car1,car2_1,car3_1遵循Compostion逻辑。但是我读过很多地方,car3_2也是组成。为什么?如果我们销毁car3_2,引擎实例仍然存在,因此应该是Aggregation。
是的,引擎仍然在car3_2实例外部,所以应该是Aggregation。
我想在Java中,很难看到差异,因为对于任何对象,您只能存储对某个堆位置的引用,而在其他编程语言(如C ++)中,您可以选择一个对象是否持有对另一个对象的引用,而一个对象却持有一个对象的引用。该对象的嵌入式副本。
但是我们在java中,正在研究生命周期...。发动机的存在时间是否比汽车长,取决于是否有人引用该发动机。除了car4之外,所有汽车都有一个公开的发动机场,任何人都可以抓住并保持引用,从而在扔掉汽车时保持发动机。
我更希望car4没有软件包(默认),甚至没有私有权限。这意味着没有人可以访问该引擎参考(除非在其他地方泄露了),并且您可以谈论成分。
编辑:将您的问题和代码示例重新读到底部,我认为问题在于如何构造它们。 Car1和car4_1确实带有它们自己隐式创建的引擎,并且由于没人抓住参考,所以汽车和引擎会同时收集垃圾。我称这种成分。
Car2_1和car3_1的行为相同,尽管引擎是明确构造的。他们将与各自的引擎一起收集垃圾。这表现相似,但也允许下一个模式。我猜它是作为诱饵引入的。
Car2_2和car3_2都共享一个明确创建的引擎,并且在main方法中存在对其的引用。一辆或两辆汽车可能会收集垃圾,但除非放弃所有三个参考,否则发动机将保持运转。因此,这可能应该显示聚合。
- Aggregation表示一种关系,其中子级可以独立于父级而存在。示例:班级(父母)和学生(孩子)。删除班级,学生仍然存在。
- Composition表示一种关系,其中子代不能独立于父代而存在。示例:房屋(父母)和房间(孩子)。房间并不与房屋分开存在。
所以,就其本质而言,对于以下任何对象,它不能是组成:>
[car3_2
不能为合成,因为它与car2_2
共享引擎。
其他人都是作文吗?从逻辑上讲,在Real Life
中,您可以从汽车上卸下发动机并将其安装在另一辆汽车上,因此汽车与发动机的关系为“聚合”。以编程方式,final
关键字可防止从Engine
中删除Car
,但不会阻止将同一引擎添加到另一辆汽车,也不会阻止该汽车被“删除”和引擎更改所有者,因此final
本身不能确保组成关系。
[当构造函数将引擎作为参数时,Car
类不能确保不共享引擎,因此不能确保组成关系。
仅当由Engine
构造函数创建Car
并且字段为final
(或有效地定为,本质上是private
,没有设置方法)时,才能保证尊重Composition的定义。
不是表示其他将Engine
作为参数的其他对象不能有效地构成。这取决于它的使用方式。例如。如果Car
是由Factory
类创建的,则工厂可以强制执行合成规则。