android框架之基礎 原型設計模式,原型設計模式也是創建型幾個模式之一,提到創建型模式工廠模式,都以為是new一個對象出來,但是原型設計模式,并不通過new創建對象。
定義:
原型模式是一種創建型設計模式,它通過復制一個已經存在的實例來返回新的實例,而不是新建實例
用途:
原型模式多用于創建復雜的或者耗時的實例, 因為這種情況下,復制一個已經存在的實例可以使程序運行更高效,或者創建值相等,只是命名不一樣的同類數據
原型模式就是把一個對象中的屬性的值賦值給另外一個對象屬性的值
使用復制也就是克隆必須要實現Cloneable接口,
public interface Cloneable {}發現這又是一個標記接口,還有就是要重寫Object類中的clone()方法
package com.prototype;public class Student implements Cloneable {private String name;private int age;public Student(String name, int age) {super();this.name = name;this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}@Overrideprotected Object clone() throws CloneNotSupportedException {Object obj = super.clone();return obj;}}
測試:
package com.prototype;public class Test {public static void main(String[] args) throws CloneNotSupportedException {Student stu = new Student("zhouguizhi", 18);System.out.println("stu="+stu);Student cloneStu = (Student) stu.clone();System.out.println("cloneStu="+cloneStu);System.out.println("name="+cloneStu.getName()+"--"+"age="+cloneStu.getAge());}}
運行結果:
stu=com.prototype.Student@2a139a55
cloneStu=com.prototype.Student@15db9742
name=zhouguizhi--age=18
你會發現克隆出來的對象內存地址值和原來的對象是不同的,所以這二個不是同一個對象,但是值是相同的,創建對象時屬性的值都是默認值,而克隆出來的對象中的值是原始對象的屬性值,
其實克隆就是類似這種把一個對象中的值賦值給另外一個對象,比如這樣子:
Student stu = new Student("zhouguizhi", 18);System.out.println("stu="+stu);Student cloneStu = new Student();cloneStu.setName(stu.getName());cloneStu.setAge(stu.getAge());
這是這種效率比較低而已,所以java會把克隆也就是clone()方法放在native層,用c處理起來效率更高.
現在Student類上添加一個朋友的屬性對象
package com.prototype;public class Student implements Cloneable {private String name;private int age;private Friend friend;public Student(String name, int age, Friend friend) {super();this.name = name;this.age = age;this.friend = friend;}public Student() {super();}public Student(String name, int age) {super();this.name = name;this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}@Overrideprotected Object clone() throws CloneNotSupportedException {Object obj = super.clone();return obj;}public Friend getFriend() {return friend;}public void setFriend(Friend friend) {this.friend = friend;}class Friend{private int age;private String name;public Friend(int age, String name) {this.age = age;this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}}}
Test.java
package com.prototype;import com.prototype.Student.Friend;public class Test {public static void main(String[] args) throws CloneNotSupportedException {Friend friend =new Student().new Friend(20,"xiaofang");System.out.println("friend="+friend);Student stu = new Student("zhouguizhi", 18,friend);Student cloneStu = (Student) stu.clone();Friend cloneFriend = cloneStu.getFriend();System.out.println("克隆后的friend="+friend);cloneFriend.setAge(99);//改變Friend對象中的值//獲取原數據fried對象中的age值System.out.println("age="+friend.getAge());}}
運行結果:
friend=com.prototype.Student$Friend@2a139a55克隆后的friend=com.prototype.Student$Friend@2a139a55age=99
從打印的結果看,明明是在克隆后的Student對象上獲取到Friend對象后改變了age的值,但是原來的值也跟著改變了,說明了這個Friend對象在內存中是共享同一個對象才會造成這樣結果
淺克隆:對值類型的成員變量進行值的復制,對引用類型的成員變量只復制引用,不復制引用的對象
從上面的問題就引出了深克隆的問題
深克隆:對值類型的成員變量進行值的復制,對引用類型的成員變量也進行引用對象的復制(會創建對象在內存中分配就不一樣)
對于上面的問題用深克隆可以解決
再次看下Student類的代碼:
package com.prototype;public class Student implements Cloneable {private String name;private int age;private Friend friend;public Student(String name, int age, Friend friend) {super();this.name = name;this.age = age;this.friend = friend;}public Student() {super();}public Student(String name, int age) {super();this.name = name;this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}@Overrideprotected Object clone() throws CloneNotSupportedException {Object obj = super.clone();Student student = (Student) obj;student.friend = (Friend) this.friend.clone();//把屬性也進行克隆return obj;}public Friend getFriend() {return friend;}public void setFriend(Friend friend) {this.friend = friend;}class Friend implements Cloneable {private int age;private String name;public Friend(int age, String name) {this.age = age;this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}@Overrideprotected Object clone() throws CloneNotSupportedException {Object obj = super.clone();return obj;}}}
Test.java
package com.prototype;public class Test {public static void main(String[] args) throws CloneNotSupportedException {Friend friend =new Friend(20,"xiaofang");System.out.println("friend="+friend);Student stu = new Student("zhouguizhi", 18,friend);Student cloneStu = (Student) stu.clone();Friend cloneFriend = cloneStu.getFriend();System.out.println("克隆后的friend="+cloneFriend);cloneFriend.setAge(99);//改變Friend對象中的值//獲取原數據fried對象中的age值System.out.println(friend==cloneFriend);System.out.println("age="+friend.getAge());}}
運行結果:
friend=com.prototype.Friend@2a139a55
克隆后的friend=com.prototype.Friend@15db9742falseage=20
從結果上看發現friend和克隆出來的cloneFriend對象不是同一個對象了,而且改變克隆后的值也不會影響之前的值了.
從深克隆中發現也用到了淺克隆,上面的Friend對象重寫了clone()方法就是淺克隆了,說明克隆可以多層嵌套.
其實使用序列化和反序列化也可以實現深克隆
package com.prototype;import java.io.ByteArrayInputStream;import java.io.ByteArrayOutputStream;import java.io.ObjectInputStream;import java.io.ObjectOutputStream;import java.io.Serializable;public class Student implements Cloneable,Serializable {private static final long serialVersionUID = 1L;private String name;private int age;private Friend friend;public Student(String name, int age, Friend friend) {super();this.name = name;this.age = age;this.friend = friend;}public Student() {super();}public Student(String name, int age) {super();this.name = name;this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public Friend getFriend() {return friend;}public void setFriend(Friend friend) {this.friend = friend;}/** * 序列化和反序列化實現深克隆 */public Object deepClone() throws Exception { //將對象寫到流里 ByteArrayOutputStream bos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(bos); oos.writeObject(this); //從流里讀回來 ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray()); ObjectInputStream ois = new ObjectInputStream(bis); return ois.readObject();}}
Test.java
package com.prototype;public class Test {public static void main(String[] args) throws Exception {Friend friend =new Friend(20,"xiaofang");System.out.println("friend="+friend);Student stu = new Student("zhouguizhi", 18,friend);Student student = (Student)stu.deepClone();Friend cloneFriend = student.getFriend();System.out.println("克隆后的cloneFriend="+cloneFriend);cloneFriend.setAge(18);//原來是20 改為18System.out.println("原friend中的age值="+friend.getAge());}}
運行結果:
friend=com.prototype.Friend@2a139a55
克隆后的cloneFriend=com.prototype.Friend@4554617c
原friend中的age值=20
看文倉www.kanwencang.com網友整理上傳,為您提供最全的知識大全,期待您的分享,轉載請注明出處。
歡迎轉載:http://www.kanwencang.com/bangong/20170303/109803.html
文章列表