面向對象編程有三大特性:封裝、繼承、多態。本文將介紹java的三大特性之封裝javascript
封裝
封裝從字面上來理解就是包裝的意思,專業點就是信息隱藏,是指利用抽象數據類型將數據和基於數據的操做封裝在一塊兒,使其構成一個不可分割的獨立實體,數據被保護在抽象數據類型的內部,儘量地隱藏內部的細節,只保留一些對外接口使之與外部發生聯繫。系統的其餘對象只能經過包裹在數據外面的已經受權的操做來與這個封裝的對象進行交流和交互。也就是說用戶是無需知道對象內部的細節(固然也無從知道),但能夠經過該對象對外的提供的接口來訪問該對象。java
對於封裝而言,一個對象它所封裝的是本身的屬性和方法,因此它是不須要依賴其餘對象就能夠完成本身的操做。數據庫
使用封裝有幾大好處:編程
一、良好的封裝可以減小耦合。this
二、類內部的結構能夠自由修改。spa
三、能夠對成員進行更精確的控制。code
四、隱藏信息,實現細節。對象
首先咱們先來看兩個類:Husband.java、Wife.javablog
1 public class Husband { 2 3 /* 4 * 對屬性的封裝 5 * 一我的的姓名、性別、年齡、妻子都是這我的的私有屬性 6 */ 7 private String name ; 8 private String sex ; 9 private int age ; 10 private Wife wife; 11 12 /* 13 * setter()、getter()是該對象對外開發的接口 14 */ 15 public String getName() { 16 return name; 17 } 18 19 public void setName(String name) { 20 this.name = name; 21 } 22 23 public String getSex() { 24 return sex; 25 } 26 27 public void setSex(String sex) { 28 this.sex = sex; 29 } 30 31 public int getAge() { 32 return age; 33 } 34 35 public void setAge(int age) { 36 this.age = age; 37 } 38 39 public void setWife(Wife wife) { 40 this.wife = wife; 41 } 42 }
1 public class Wife { 2 private String name; 3 private int age; 4 private String sex; 5 private Husband husband; 6 7 public String getName() { 8 return name; 9 } 10 11 public void setName(String name) { 12 this.name = name; 13 } 14 15 public String getSex() { 16 return sex; 17 } 18 19 public void setSex(String sex) { 20 this.sex = sex; 21 } 22 23 public void setAge(int age) { 24 this.age = age; 25 } 26 27 public void setHusband(Husband husband) { 28 this.husband = husband; 29 } 30 31 public Husband getHusband() { 32 return husband; 33 } 34 35 }
從上面兩個實例咱們能夠看出Husband裏面wife引用是沒有getter()的,同時wife的age也是沒有getter()方法的。至於理由我想各位都懂的,男人嘛深屋藏嬌妻嘛,沒有那個女人願意別人知道她的年齡。繼承
因此封裝把一個對象的屬性私有化,同時提供一些能夠被外界訪問的屬性的方法,若是不想被外界方法,咱們大可沒必要提供方法給外界訪問。可是若是一個類沒有提供給外界訪問的方法,那麼這個類也沒有什麼意義了。好比咱們將一個房子看作是一個對象,裏面的漂亮的裝飾,如沙發、電視劇、空調、茶桌等等都是該房子的私有屬性,可是若是咱們沒有那些牆遮擋,是否是別人就會盡收眼底呢?沒有一點兒隱私!就是存在那個遮擋的牆,咱們既可以有本身的隱私並且咱們能夠隨意的更改裏面的擺設而不會影響到其餘的。可是若是沒有門窗,一個包裹的嚴嚴實實的黑盒子,又有什麼存在的意義呢?因此經過門窗別人也可以看到裏面的風景。因此說門窗就是房子對象留給外界訪問的接口。
經過這個咱們還不能真正體會封裝的好處。如今咱們從程序的角度來分析封裝帶來的好處。若是咱們不使用封裝,那麼該對象就沒有setter()和getter(),那麼Husband類應該這樣寫:
1 public class Husband { 2 public String name ; 3 public String sex ; 4 public int age ; 5 public Wife wife; 6 }
咱們應該這樣來使用它:
1 Husband husband = new Husband(); 2 husband.age = 30; 3 husband.name = "張三"; 4 husband.sex = "男"; //貌似有點兒多餘
可是那天若是咱們須要修改Husband,例如將age修改成String類型的呢?你只有一處使用了這個類還好,若是你有幾十個甚至上百個這樣地方,你是否是要改到崩潰。若是使用了封裝,咱們徹底能夠不須要作任何修改,只須要稍微改變下Husband類的setAge()方法便可。
1 public class Husband { 2 3 /* 4 * 對屬性的封裝 5 * 一我的的姓名、性別、年齡、妻子都是這我的的私有屬性 6 */ 7 private String name ; 8 private String sex ; 9 private String age ; /* 改爲 String類型的*/ 10 private Wife wife; 11 12 public String getAge() { 13 return age; 14 } 15 16 public void setAge(int age) { 17 //轉換便可 18 this.age = String.valueOf(age); 19 } 20 21 /** 省略其餘屬性的setter、getter **/
其餘的地方依然那樣引用(husband.setAge(22))保持不變。
其餘的地方依然那樣引用(husband.setAge(22))保持不變。
到了這裏咱們確實能夠看出,封裝確實可使咱們容易地修改類的內部實現,而無需修改使用了該類的客戶代碼。
咱們在看這個好處:能夠對成員變量進行更精確的控制。
仍是那個Husband,通常來講咱們在引用這個對象的時候是不容易出錯的,可是有時你迷糊了,寫成了這樣:
1 Husband husband = new Husband(); 2 husband.age = 300;
也許你是由於粗心寫成了,你發現了還好,若是沒有發現那就麻煩大了,逼近誰見過300歲的老妖怪啊!可是使用封裝咱們就能夠避免這個問題,咱們對age的訪問入口作一些控制(setter)如:
1 public class Husband { 2 3 /* 4 * 對屬性的封裝 5 * 一我的的姓名、性別、年齡、妻子都是這我的的私有屬性 6 */ 7 private String name ; 8 private String sex ; 9 private int age ; /* 改爲 String類型的*/ 10 private Wife wife; 11 12 public int getAge() { 13 return age; 14 } 15 16 public void setAge(int age) { 17 if(age > 120){ 18 System.out.println("ERROR:error age input...."); //提示錯誤信息 19 }else{ 20 this.age = age; 21 } 22 23 } 24 25 /** 省略其餘屬性的setter、getter **/ 26 27 }
上面都是對setter方法的控制,其實經過使用封裝咱們也可以對對象的出口作出很好的控制。例如性別咱們在數據庫中通常都是已一、0方式來存儲的,可是在前臺咱們又不能展現一、0,這裏咱們只須要在getter()方法裏面作一些轉換便可。
1 public String getSexName() { 2 if("0".equals(sex)){ 3 sexName = "女"; 4 } 5 else if("1".equals(sex)){ 6 sexName = "男"; 7 } 8 else{ 9 sexName = "人妖???"; 10 } 11 return sexName; 12 }
在使用的時候咱們只須要使用sexName便可實現正確的性別顯示。同理也能夠用於針對不一樣的狀態作出不一樣的操做。
1 public String getCzHTML(){ 2 if("1".equals(zt)){ 3 czHTML = "<a href='javascript:void(0)' onclick='qy("+id+")'>啓用</a>"; 4 } 5 else{ 6 czHTML = "<a href='javascript:void(0)' onclick='jy("+id+")'>禁用</a>"; 7 } 8 return czHTML; 9 }