在設計模式中的prototype模式中,要特别留意的是其中的深複制和淺複制,現在小結一下
1 淺複制
當進行淺複制時,如果類中包含了子對象,當這個類的包含的子引用對象發生改變時,這個變化會同時出現在它的淺複制克隆的對象中
去,比如
public class Lay1 implements Cloneable {
public int x;
public Lay2 lay2;
public Object clone()
{
Object clone=null;
try
{
clone=super.clone();
}
catch (CloneNotSupportedException e)
return clone;
}
}
Lay1中包含子對象lay2了,lay2指向一個類Lay2
public class Lay2 implements Cloneable {
public int y;
}
客戶程式
public class Client {
public static void main(String argv[])
{
Lay1 obj1=new Lay1();
obj1.lay2=new Lay2();
obj1.x=1;
obj1.lay2.y=1;
Lay1 obj2=(Lay1)obj1.clone();
obj2.x=2;
obj2.lay2.y=2;
System.out.println("obj1.x is:"+obj1.x+"\tObj1.lay2.y is:"+obj1.lay2.y);
System.out.println("obj2.x is:"+obj2.x+"\tObj2.lay2.y is:"+obj2.lay2.y);
}
輸出為
obj1.x i s:1 obj1.lay2.y=2
obj2.x is 2 obj2.lay2.y=
可以看到 obj1目前層的對象别clone了一份,但clone對象的值的改變不反映到父對象,但修改其引用的子對象lay2的值,會反映到父方,因為大家都是指向同一個地方嘛。
為了深複制,可以這樣做
public int x;
public Lay2 lay2;
public Object clone() {
Lay1 temp=null;
try {
temp=(Lay1)super.clone();
temp.lay2=(Lay2)lay2.clone();
}
catch (CloneNotSupportedException e) {
// should never happen
return temp;
public int y;
Object clone = null;
clone = super.clone ();
return clone;
可以看到。輸出是
obj1.x is:1 Obj1.lay2.y is:1
obj2.x is:2 Obj2.lay2.y is:2
另外,給出C#版本的代碼,注意C#中淺複制用到的memberwiseclone()(轉自
javascript:void(0))
using System;


class ShallowCopy : ICloneable
{
public int[] v =
{1,2,3};
public Object Clone()
return this.MemberwiseClone();
public void Display()
foreach(int i in v)
Console.Write( i + ", ");
Console.WriteLine();


class Client
public static void Main()
ShallowCopy sc1 = new ShallowCopy();
ShallowCopy sc2 = (ShallowCopy)sc1.Clone();
sc1.v[0] = 9;
sc1.Display();
sc2.Display();
ShallowCopy對象實作了一個淺拷貝,是以當對sc1進行克隆時,其字段v并沒有克隆,這導緻sc1與sc2的字段v都指向了同一個v,是以,當修改了sc1的v[0]後,sc2的v[0]也發生了變化。
深複制


class DeepCopy : ICloneable
// 預設構造函數
public DeepCopy()
// 供Clone方法調用的私有構造函數
private DeepCopy(int[] v)
this.v = (int[])v.Clone();
// 構造一個新的DeepCopy對象,構造參數為
// 原有對象中使用的 v
return new DeepCopy(this.v);


DeepCopy dc1 = new DeepCopy();
DeepCopy dc2 = (DeepCopy)dc1.Clone();
dc1.v[0] = 9;
dc1.Display();
dc2.Display();
這次在克隆的時候,不但克隆對象本身,連裡面的數組字段一并克隆。是以,最終列印出來的dc1與dc2不同。