1. 程式人生 > >重溫Java——封裝

重溫Java——封裝

從接觸Java到現在一年多了,隨著程式碼量的累積,愈發的覺得有種迫切的心理,往深處去學習,然後就想著從頭開始,藉著Java程式設計思想、Java核心技術、Effective Java以及網路上的文章,對知識進行整合再輸出,重新梳理之前囫圇嚥下去的知識點,打牢基礎的同時也做出一點自己的貢獻。

我們都知道,面向物件的幾個特性——封裝、繼承、多型,從字面的來看,封就是隱藏資訊,裝就是統一提供檢視/修改方法,專業點的解釋就是將資訊隱藏,然後利用抽象的資料結構將資料和基於資料的操作封裝在一起,使其構成一個不可分割的獨立實體,資料被隱藏在抽象資料型別的內部,儘可能的隱藏內部細節,只暴露一些可供外部介面訪問/操作的介面。使用者在不知道知道物件內部的實現細節情況下,仍然可以通過介面訪問該物件,這樣也可以方便我們在使用者無感知的情況下做出些修改。

所以通過上面那段話,我們不難總結出來,封裝需要我們做以下幾件事情:

1.將想隱藏的資料定義為私有的資料域;

2.提供公有的域訪問器方法;

3.提供公有的域更改器方法。

對於封裝而言,一個物件所封裝的是自己的屬性和方法,所以它是不需要依賴其他物件就可以完成自己的操作。

使用封裝有以下好處:

1.良好的封裝可以減少耦合;

2.類內部的介面可以自由修改;

3.可以對成員進行更精確的控制;

4.隱藏資訊,實現細節

 

只是這麼說似乎有些抽象,下面我們結合程式碼解釋說明下:

封裝的操作步驟與程式碼實現

1.將想隱藏的資料定義為私有的資料域;——修改屬性的可見性(一般為private)

2.提供公有的域訪問器方法;——建立getter方法

3.提供公有的域更改器方法。——建立setter方法

public class Employee{

/*
* 對屬性的封裝
* 一個人的姓名、性別、年齡、薪酬等都是這個人的私有屬性
*/

    private String name ;

    private String sex ;

    private int age ;

    private int salary;

/*
* setter()、getter()是該物件對外開放的介面,此處省略setter、getter方法
*/
}

在這裡,如果我們想隱藏某些資料,只需要去除對應的getter方法即可,外部類就無法獲取到對應的數值,隱藏了資訊。比如,一個員工的薪酬是私密資訊,那麼我們把薪酬的getter方法去掉,外界即無法知道員工的薪酬是多少。

所以封裝把一個物件的屬性私有化後,如果不想被訪問,不提供對應的getter方法即可。

下面我們再看一個例子

如果沒有getter、setter方法,我們的Employee類初始化的時候就要這麼做,

Employee employee= new Employee();

employee.age = 30;

employee.name = "張三";

employee.sex = "男";

現在我們需要修改Employee類,比如講age修改為String型別,在沒有封裝的情況下,我們需要對每一處初始化程式碼都進行修改。但是如果使用了封裝,我們不需要修改程式碼中初始化部分,只需要修改setAge()方法即可。

public class Employee{

/*

* 對屬性的封裝

* 一個人的姓名、性別、年齡都是這個人的私有屬性

*/

private String name ;

private String sex ;

private String age ;

private int salary;

public String getAge() {

return age;

}

public void setAge(int age) {

//轉換即可

this.age = String.valueOf(age);

}

/** 省略其他屬性的setter、getter **/

}

這樣其他地方依然使用employee.setAge(30)不需要改變,但是型別已經改成String了。在這裡,我們看到了封裝對成員的精確控制。

 

還是那個例子,我們在初始化的時候可能會

Employee employee= new Employee();

employee.salary= -1000;

這個問題不該發生,薪酬怎麼會是負的呢,但是在初始化的時候,我們不能完全杜絕。可是如果我們使用封裝的話,就可以避免這個問題,因為我們可以對salary的setter方法做一個限制,比如:

public class Employee{

/*

* 對屬性的封裝

* 一個人的姓名、性別、年齡、薪酬都是這個人的私有屬性

*/

private String name ;

private String sex ;

private int age ;

private int salary;

public int getSalary() {

return salary;

}

public void setSalary(int age) {

      if(salary < 0){

           System.out.println("ERROR:error age input...."); //提示錯誤資訊

       }else{

           this.salary= salary;

      }

}

/** 省略其他屬性的setter、getter **/

}

不僅僅是setter方法,我們也可以通過封裝對物件的出口(即getter方法)做出控制,例如性別我們在資料庫中都是以1/0方式來儲存的,但是在前臺又不能展示1/0,所以我們只需要在getter方法裡做一些轉換即可。

比如:

public String getSexName() {

   if("0".equals(sex)){

      sexName = "女";

   }

   else if("1".equals(sex)){

      sexName = "男";

   }

   else{

      sexName = "人妖???";

   }

   return sexName;

}

看完上面幾個例子以後,這個時候我們再回頭,看最開始那段,封裝的優點——

1.良好的封裝可以減少耦合;

2.類內部的介面可以自由修改;

3.可以對成員進行更精確的控制;

4.隱藏資訊,實現細節

有沒有就覺得印象深刻了很多呢。