我真的很难理解构图和聚合。在下面的代码中,我想知道以下哪个car实例使用组合逻辑或聚合逻辑。
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遵循组合逻辑。但我读过许多地方,car3_2也是作文。为什么?如果我们销毁car3_2,那么引擎实例就会存在,因此应该是聚合。
发布于 2019-11-09 04:51:00
因此,根据这种性质,它不可能是任何物体的组成:
completes)
car3_2不能是组合,因为它与car2_2共享引擎。
其他的都是作文吗?从逻辑上讲,在真实生活中,你可以将引擎从汽车上移出并安装到另一辆车中,这样汽车引擎之间的关系就会聚合起来。
从编程上讲,final关键字可以防止从Car中删除Engine,但它并不能阻止将同一个引擎添加到另一辆汽车,也不会阻止汽车被“删除”,也不会阻止引擎改变车主,因此final本身并不能确保组合关系。
当构造函数接受引擎作为参数时,Car类不能确保引擎不是共享的,因此不能确保组合关系。
只有当Engine由Car构造函数创建并且字段是final (或者实际上是最终的,本质上是没有setter方法的private )时,才能保证组合的定义得到遵守。
这并不意味着其他以Engine为参数的组合不能有效地进行组合。这取决于它的使用方式。例如,如果Car是由Factory类创建的,工厂可以强制执行组合规则。
发布于 2019-11-08 15:38:39
是的,引擎仍然存在于car3_2实例之外,所以应该是聚合。
发布于 2019-11-08 15:49:18
我猜,在Java中,很难看出不同之处,因为对于任何对象,您只能存储对某个堆位置的引用,而在其他编程语言(如C++ )中,您可以选择一个对象是否包含对另一个对象的引用,而一个对象持有该对象的嵌入式副本。
但我们在爪哇,看着生命周期.发动机是否存在时间比汽车长,取决于某人是否持有该引擎的参考文件。除了car4之外,所有的汽车都有一个公开可用的引擎字段,任何人都可以抓取并保留参考信息,从而在扔掉汽车的同时保留引擎。
我更希望car4没有包(默认),甚至是私有访问。这意味着任何人都不应该访问该引擎引用(除非在其他地方泄漏),并且您可以谈论合成。
编辑:重新阅读你的问题和代码样本到底部,我认为问题是如何构建它们。Car1和car4_1提供了他们自己隐式创建的引擎,当没有人获取引用时,汽车和引擎同时被垃圾收集。我把这叫做作文。
Car2_1和car3_1的行为是一样的,尽管引擎是显式构造的。他们会把垃圾和各自的引擎一起收集起来。这样做的行为类似,但也允许下一个模式。我想它是作为诱饵引入的。
Car2_2和car3_2都共享一个显式创建的引擎,对它的引用出现在主方法中。其中一辆或两辆车都可以被垃圾收集,但除非放弃所有三种引用,否则引擎将继续使用。因此,这可能会显示聚合。
https://stackoverflow.com/questions/58769204
复制相似问题