1

我有一个类图,我需要该图的副本。我将修改图形对象的内部结构(例如:删除边等)。我有两种实现图表的方法。

  1. 复制构造函数
  2. 一个名为“getGraph() { return new Graph(this)}”的方法。getGraph 这个方法可以做一个防御性的拷贝。

据我了解,复制构造函数的唯一优点是随意复制。这意味着如果我不想修改图形对象,则不需要“getGraph”来进行防御性复制。

现在回到我的问题。

  1. 使用复制构造函数更好还是使用返回 self 对象副本的函数更好?
  2. 为什么 ?
4

4 回答 4

2

在不知道你需要这个做什么的情况下,最好将复制定义为一种方法,因为潜在的子类可以覆盖一个方法。如果Graph有一个子类,例如为每个节点添加颜色,则在其中调用复制构造函数Graph只能复制普通图,从而丢失子类中的附加信息和功能。另一方面,可以在子类中覆盖复制图的方法。

您可能会发现该Object.clone方法很有帮助,但请记住它的要求(必须实现Cloneble和覆盖该clone方法)和限制(仅制作浅拷贝),您不妨从头开始编写您的复制方法。

于 2013-08-22T06:36:19.453 回答
1

据我了解你的问题

在复制构造函数中,你会做类似的事情

Graph copy = new Graph(objectToBeCloned);

在 getGraph() 你会做

Graph copy = objectToBeCloned.getGraph();

我建议让您的 Graph 类实现Cloneable接口和覆盖clone() 方法以获得您需要的深层副本。

于 2013-08-22T06:35:47.103 回答
1

我会说复制构造函数比 Graph 对象内的 getGraph 方法具有更多语义。所以在两者之间我更喜欢一个复制构造函数。

请不要考虑使用克隆,它是被设计破坏的,阅读Object Identity了解更多信息。您还有一些替代方案,在这里表达:克隆与复制构造函数

于 2013-08-22T08:41:31.233 回答
1

我不确定您是否仍在寻找此问题的答案,但由于该问题未标记为已回答,因此我将回答它。

由于您选择使用复制构造函数

Graph clonedGraph = new Graph(originalGraph);

或防御副本

Graph clonedGraph = originalGraph.getGraph();

我可以告诉你,你知道它的缺点Object.clone(),并且我会建议你使用防御性复制策略,因为它是多态的,并且还给你反转控制或依赖注入的优势。

如果您有一个子类Graph(将来可能需要)并尝试将该子类的对象分配给的引用,Graph然后尝试为其创建副本,则复制构造函数策略将失败。您可以阅读有关Java 克隆的更多信息 - 为什么复制构造函数不够

于 2017-01-15T18:07:15.587 回答