多多色-多人伦交性欧美在线观看-多人伦精品一区二区三区视频-多色视频-免费黄色视屏网站-免费黄色在线

國內最全IT社區平臺 聯系我們 | 收藏本站
阿里云優惠2
您當前位置:首頁 > php框架 > 框架設計 > java語言實現創建型設計模式―原型模式(Prototype)

java語言實現創建型設計模式―原型模式(Prototype)

來源:程序員人生   發布時間:2015-05-06 08:47:40 閱讀次數:3288次

1、描寫

原型模式是通過1個原型對象來標明要創建的對象的類型,然后用復制這個原型對象的方法來拷貝創建更多的同類型對象。例如我們在程序的動態運行進程中有了1個對象,這個對象中包括了1系列的有效數據,我們此時需要1個和該對象完全相同的新對象,并且在拷貝以后,新舊對象之間沒有任何聯系,對任何1個對象的更改都不影響另外一個對象。

在java中所有類都默許繼承自java.lang.Object類,在這個Object類中有1個clone()方法,該方法將返回Object對象的1個拷貝。

我們讓需要被拷貝的類實現 Cloneable 接口,該接口用來唆使Object.clone()方法可以合法地對該類實例進行按字段復制。如果在沒有實現Cloneable 接口的實例上調用 Object 的 clone 方法,則會致使拋出 CloneNotSupportedException 異常。


注意Cloneable接口是1個標記接口,該接口中沒有任何別的方法,只是作為標記來標明這個類可以合法的使用Object類的clone()方法來產生該實例的1個副本。

Cloneable接口是標記接口以外還有Serializable接口(用于類啟用其序列化功能,未實現此接口的類將沒法使其任何狀態序列化或反序列化)、RandomAccess接口List 實現中所使用的標記接口,用來表明其支持快速(通常是固定時間)隨機訪問,從而在將其利用到隨機或連續訪問列表時能提供良好的性能)、Remote接口Remote 接口用于標識其方法可以從非本地虛擬機上調用的接口。任何遠程對象都必須直接或間接實現此接口。只有在“遠程接口(擴大java.rmi.Remote 的接口)中指定的這些方法才可遠程使用,實現類可以實現任意數量的遠程接口,并且可以擴大其他遠程實現類。RMI 提供1些遠程對象實現可以擴大的有用類,這些類便于遠程對象創建)。


2、原型設計模式的優缺點

優點:在原型模式中,可以動態地添加產品類,而且不會對整天結構產生影響,只是復制了1個對象而已。

缺點:由于原型模式要讓每一個類實現Cloneable 接口,并重寫Object類中的clone()方法,而且原型模式在實現深拷貝的時候需要補充更多的代碼,這無疑增加了1定的代碼量。


3、源代碼

3.1 淺拷貝:如果待拷貝的對象中存在對象類型和援用類型,那末只拷貝對象和援用類型的地址,而是真正拷貝對象和援用中的數據。

package tong.day5_1.dogCase; import java.util.ArrayList; /** * DogClone實現了Cloneable接口,重寫clone()方法,調用父類的clone()拷貝1個對象并返回,Dog類并沒有clone()方法,這是淺拷貝的模式。 * 淺拷貝:基本數據類型確切另外拷貝了1個副本,但是對對象類型和援用類型則只拷貝對象或援用的地址, * 致使拷貝的對象中的對象類型的援用指向同1個對象,只要有1個修改了,就會影響另外一個對象中的數據。 * @author tong * */ public class ShallowClone { public static void main(String[] args) { //拷貝之前數據的值 DogClone dogClone = new DogClone(); System.out.println("原來的dogClone.basicCount="+dogClone.basicCount); System.out.println("原來的dogClone.dog="+dogClone.dog); System.out.println("原來的dogClone.arraylist="+dogClone.arrayList); DogClone dogClone2 = (DogClone) dogClone.clone(); System.out.println("-----------------------"); //對拷貝的對象中的對象類型和援用類型的數據進行變更,則會影響另外一個對象的數據;基本類型是進行值拷貝所以產生另外一個副本,對原數據不會有影響 dogClone2.basicCount = 2; Dog dog = dogClone2.dog; dog.changeCount(); dogClone2.arrayList.add("java"); //原對象中的基本數據類型的值不變 System.out.println("后來的dogClone.basicCount="+dogClone.basicCount); System.out.println("后來的dogClone.dog="+dogClone.dog); System.out.println("后來的dogClone.arrayList="+dogClone.arrayList); System.out.println("dogClone2.basicCount="+dogClone2.basicCount); System.out.println("dogClone2.dog="+dogClone2.dog); System.out.println("dogClone2.arrayList="+dogClone2.arrayList); } } class Dog{ public int legCount; public Dog(int legCount) { this.legCount = legCount; } public void changeCount() { this.legCount +=5; } //重寫Dog類的toString()方法,在輸出dog對象時調用該方法 @Override public String toString() { return Integer.toString(legCount); } } //DogClone實現了Cloneable接口,只要重寫Object中的clone()便可根據自己的需要拷貝對象 class DogClone implements Cloneable{ //基本數據類型拷貝時會直接拷貝數據值的1個副本,也就是說拷貝后產生的legCount數值和原來被拷貝的值沒有任何關系 public int basicCount; //Dog對象類型,在使用淺拷貝的時候,拷貝的是棧中對象的地址,而不是對象地址所指向的堆內存的真實數據 public Dog dog = new Dog(5); //ArrayList援用類型,在淺拷貝時,只拷貝援用的地址,而不是拷貝援用所指向的堆內存中的字符串 public ArrayList<String> arrayList = new ArrayList<String>(); public DogClone() { basicCount = 4; arrayList.add("hello"); arrayList.add("world"); } //重寫了clone()返回1個DogClone類的副本對象 @Override protected Object clone(){ DogClone dogClone = null; try { dogClone = (DogClone) super.clone(); } catch (CloneNotSupportedException e) { e.printStackTrace(); } return dogClone; } }
運行結果:

淺拷貝


3.2 深拷貝:DogClone實現了Cloneable接口,重寫clone()方法,調用父類的clone()拷貝1個對象,并顯式調用dog對象和arrayList對象的拷貝方法返回該類對象,這樣拷貝產生的對象和原來的對象就互不干擾,相互獨立。

package tong.day5_1.deepClone; import java.util.ArrayList; /** * DogClone實現了Cloneable接口,重寫clone()方法,調用父類的clone()拷貝1個對象,并顯式調用dog對象和arrayList對象的拷貝方法返回該類對象,這是深拷貝的模式。 * 深拷貝:基本數據類型確切另外拷貝了1個副本,但是對對象類型和援用類型則默許的是只拷貝對象或援用的地址, * 如果想要使這兩種類型也拷貝對象和援用中的數據,那末就需要在重寫的clone()方法中顯式地調用該對象或援用類型的clone()方法。 * 所以我們需要讓Dog類實現Cloneable接口使其具有拷貝能力,ArrayList間接繼承了Object接口,本身就有clone()方法。 * @author tong * */ public class DeepClone { public static void main(String[] args) { // 拷貝之前數據的值 DogClone dogClone = new DogClone(); System.out.println("原來的dogClone.basicCount=" + dogClone.basicCount); System.out.println("原來的dogClone.dog=" + dogClone.dog); System.out.println("原來的dogClone.arraylist=" + dogClone.arrayList); DogClone dogClone2 = (DogClone) dogClone.clone(); System.out.println("-----------------------"); // 這里進行的是深拷貝,對拷貝的對象中的對象類型和援用類型的數據進行變更,不會影響另外一個對象的數據;基本類型是進行值拷貝所以產生另外一個副本,對原數據也不會有影響 dogClone2.basicCount = 2; Dog dog = dogClone2.dog; dog.changeCount(); dogClone2.arrayList.add("java"); // 原對象中所有數據的值都不變 System.out.println("后來的dogClone.basicCount=" + dogClone.basicCount); System.out.println("后來的dogClone.dog=" + dogClone.dog); System.out.println("后來的dogClone.arrayList=" + dogClone.arrayList); System.out.println("dogClone2.basicCount=" + dogClone2.basicCount); System.out.println("dogClone2.dog=" + dogClone2.dog); System.out.println("dogClone2.arrayList=" + dogClone2.arrayList); } } //為了實現深拷貝,我們讓Dog類實現Cloneable接口并重寫該接口中的clone()方法 class Dog implements Cloneable { public int legCount; public Dog(int legCount) { this.legCount = legCount; } public void changeCount() { this.legCount += 5; } // 重寫Dog類的toString()方法,在輸出dog對象時調用該方法 @Override public String toString() { return Integer.toString(legCount); } //重寫clone()方法,使其dog對象具有自我復制的能力 @Override protected Object clone() { Dog dog = null; try { dog = (Dog) super.clone(); } catch (CloneNotSupportedException e) { e.printStackTrace(); } return dog; } } ////為了進行DogClone對象的拷貝,我們讓DogClone類實現Cloneable接口并重寫重寫Object中的clone()方法 class DogClone implements Cloneable { // 基本數據類型拷貝時會直接拷貝數據值的1個副本,也就是說拷貝后產生的legCount數值和原來被拷貝的值沒有任何關系 public int basicCount; // Dog對象類型,在使用淺拷貝的時候,拷貝的是棧中對象的地址,而不是對象地址所指向的堆內存的真實數據 public Dog dog = new Dog(5); // ArrayList援用類型,在淺拷貝時,只拷貝援用的地址,而不是拷貝援用所指向的堆內存中的字符串 public ArrayList<String> arrayList = new ArrayList<String>(); public DogClone() { basicCount = 4; arrayList.add("hello"); arrayList.add("world"); } //重寫了clone()返回1個DogClone類的副本對象 @Override protected Object clone() { DogClone dogClone = null; try { dogClone = (DogClone) super.clone(); } catch (CloneNotSupportedException e) { // TODO Auto-generated catch block e.printStackTrace(); } //顯式調用dog對象的clone()返回1個dog對象的副本 dogClone.dog = (Dog) dog.clone(); //顯式調用arrayList對象的clone()返回1個arrayList對象的副本 dogClone.arrayList = (ArrayList<String>) arrayList.clone(); return dogClone; } }
運行結果:

深拷貝



生活不易,碼農辛苦
如果您覺得本網站對您的學習有所幫助,可以手機掃描二維碼進行捐贈
程序員人生
------分隔線----------------------------
分享到:
------分隔線----------------------------
關閉
程序員人生
主站蜘蛛池模板: 草的好爽| 日韩欧美在线观看 | 久草福利在线播放 | 久久久久无码国产精品一区 | 亚洲欧美视频一区二区 | 亚洲伊人久久网 | 免费福利午夜影视网 | 国内精品免费一区二区三区 | 久久大香伊焦在人线免费 | 亚洲精品人成网在线播放影院 | 老司机午夜精品视频播放 | 一级做a爱过程免费视频日本 | 中文字幕第6页 | 99国产精品欧美久久久久久影院 | 国产三级视频在线 | 亚洲水蜜桃久久综合网站 | 欧美一级片手机在线观看 | 日韩欧美一区二区不卡看片 | 亚洲综合视频在线 | 亚洲精品图片 | 免费看黄色的网址 | 亚洲成a人片77777kkkk | 一级毛片aaaaaa视频免费看 | 高清午夜线观看免费 | 波多野吉衣 免费一区 | 图片区小说区校园 | 中文字幕乱码二三区免费 | 乱人伦99久久 | 91日本在线观看亚洲精品 | www亚洲成人| 国产成人精品免费久久久久 | 老司机免费视频 | 欧美一级特黄特黄毛片 | 456在线观看| 亚洲黄色影视 | 亚洲aⅴ天堂| 欧美日韩第三页 | 伊人影院视频 | 亚洲欧美久久 | 国产欧美久久久精品 | 伊人.com|