原型模式小试(三)

2014-11-23 21:59:38 · 作者: · 浏览: 3
Fruit newFruit = (Fruit) ((Apple)fruit).clone();
8 System.out.println("new Fruit : " + newFruit);
9 System.out.println("前后是否为同一对象?" + (fruit == newFruit));
10 }
11 }
复制代码
4、结果:
Fruit:Apple [avgSize=5.0, price=90.0, productionArea=新疆]
new Fruit : Apple [avgSize=5.0, price=90.0, productionArea=新疆]
前后是否为同一对象?false
个人认为,方便而言,还不如自己手动实现原型模式。
由于Java的原型使用RTTI的机制,速度块,若需要克隆重量级或复杂的对象时适合使用。不过要注意的是,Java的原型模式属于浅度克隆。下面我们会讲如何使用Java的原型模式实现深度克隆。
这里再补充一点:
我们来看,static Fruit fruit = new Apple(90, 5, "新疆");
对于对象fruit,它的编译时类型是Fruit,运行时类型是Apple,所以fruit对象只能显式调用Fruit接口所有的方法。而这其中包含了Object类除了clone()方法之外的所有方法。Java中,接口和类是一个并列的概念
我们可以认为接口是一种特殊的类,它默认实现了Object中除了clone()之外的像toString()、getClass等一系列Object方法。
四、深度克隆和浅度克隆
  克隆分为深度克隆和浅度克隆。假设我们现在有一个对象,这个对象有一个引用属性是另一个对象。我们知道,引用属性的本质就是一个内存地址。按照上文的复制,我们会将复制对象的引用属性也一同复制,这样一来,复制对象和被复制对象的该属性都指向同一内存地址了。这就违背了我们克隆的初衷。而这个就是浅度克隆。
  相对的,深度克隆就是克隆之后,复制对象和被复制对象是完全不想干的。即对于对象的引用属性,我们重新克隆一次。
  下面是Java克隆、深度克隆的简单示例:
1、首先是一个包含刚才Fruit类的Businessman对象:
复制代码
1 public class Businessman implements Cloneable {
2
3 private String name;
4 private Fruit fruit;
5
6 @Override
7 public String toString()
8 {
9 return "Businessman [name=" + name + ", fruit=" + fruit + "]";
10 }
11
12 public Businessman(String name, Fruit fruit)
13 {
14 super();
15 this.name = name;
16 this.fruit = fruit;
17 }
18
19 public String getName()
20 {
21 return name;
22 }
23
24 public void setName(String name)
25 {
26 this.name = name;
27 }
28
29 public Fruit getFruit()
30 {
31 return fruit;
32 }
33
34 public void setFruit(Fruit fruit)
35 {
36 this.fruit = fruit;
37 }
38 //克隆方法
39 public Object clone(){
40 //先克隆一下引用变量
41 Fruit f = (Fruit) ((Apple)fruit).clone();
42 Businessman man = new Businessman(name,f);
43 return man;
44 }
45 }
复制代码
2、测试一下:
复制代码
1 package prototype;
2
3 public class Client {
4
5 public static void main(String[] args) {
6 //水果类
7 Fruit fruit = new Apple(90, 5, "新疆");
8 //商人
9 Businessman man1 = new Businessman("张三",fruit);
10
11 System.out.println("man1:" + man1);
12 //克隆
13 Businessman man2 = (Businessman) man1.clone();
14
15 System.out.println("man2 : " + man2);
16 System.out.println("man1和man2前后是否为同一对象?" + (man1 == man2));
17 System.out.println("两者的属性呢?"+(man1.getFruit()==man2.getFruit()));
18 }
19 }
复制代码
3、结果如下:
man1:Businessman [name=张三, fruit=Apple [avgSize=5.0, price=90.0, productionArea=新疆]]
man2 : Businessman [name=张三, fruit=Apple [avgSize=5.0, price=90.0, productionArea=新疆]]
man1和man2前后是否为同一对象?false
两者的属性呢?false