封裝
介紹封裝的概念。
物件導向最基本的原則,把真實世界的某個事物包成物件,裡面的資訊不對外公開,只公開某些特定方法讓別人使用,內部的實做及資料都隱藏起來,不讓人直接使用,也不需要讓別人直接使用。也就是所謂的 資訊隱藏(Information Hiding)
設想一個例子,
提款機,你不知道它裡面還有多少錢,也不知道內部的運做,不知道哪家公司生產的機器,但你還是會去使用他提供的方法:查詢餘額、提款。 因為他只開放這兩個方法給一般人使用,你要使用這兩個方法需要帶入的參數是提款卡及密碼,就可以完成你的需求。
class 提款機{
private int 剩餘現金;
private boolean 身分確認(提款卡、密碼){
...
}
private void 吐鈔(){
...
}
public void 提款(提款卡、密碼){
if(身分確認(提款卡、密碼) == true)
吐鈔();
}
public void 查詢餘額(提款卡、密碼){
...
}
}
當然實際上更為複雜且嚴密(而且我對提款機不熟),但在怎麼複雜,使用上一般使用者只要知道使用哪些公開的方法就好(雖然不熟但我會領錢、查餘額),剩下的就是設計這個類別的設計師要負責的工作。
常用修飾子 private 、 public
private 私有
private是資訊隱藏會普遍使用的修飾子,開放全限最低,只有自己類別的成員能夠存取。
public 公開
與private相反,public是任何人都可以調用,通常用來表示這個方法可以供一般人呼叫,一個public的方法內可以呼叫多個private的方法來實作需要的功能。
其他修飾子請參考『存取修飾子』章節。
物件導向是將『資料及其方法』包裝成物件,而資料、方法的劃分都是設計師決定的,但要記得物件的核心是資料,而不是方法。 (data是主角)
封裝的概念是將資訊隱藏,只透過某些公開的方法讓外界存取使用。
Getter、Setter
為了資訊隱藏,我們常把重要資料設為private,要供別人(甚至自己)存取的時候,通常會利用getter()及setter()這種透過公開方法間接的存取。
來看個例子,學生的類別有姓名年齡3個欄位,提供兩個setter兩個getter:
class Student{
private String firstName;
private String lastName;
private int age = -1;
public void setName(String first,String last){
if( first == null || last == null || first.length()==0 || last.length()==0 ){
System.out.println("ERROR: name輸入錯誤,名字姓氏不得為空");
}else{
firstName = first;
lastName = last;
}
}
public void setAge(int a){
if(a < 0){
System.out.println("ERROR: age輸入錯誤,年齡不可能為負數");
}else{
age = a;
}
}
public String getName(){
if( firstName==null || lastName==null)
return "unset";
else
return firstName + lastName;
}
public int getAge(){
return age;
}
}// end of class Student
這是常見的設計方法,資料成員的部份我都設為private,而公開了setName(.)及setAge(.)讓別人呼叫來設定name及age的值,這就是透過公開方法間接的設定隱藏的欄位,好處是我這樣寫可以在設定欄位前先做一些前處理(以上述程式來說就是檢查參數的合法性)。
在getter的部份,也公開了兩個方法可以讓別人存取到內部隱藏的成員,以getName()來說,可以在回傳出去前多做一步處理(這裡是把名跟姓串起來),這樣的設計方式是常見且容易維護的。
測試程式:
class Test {
public static void main(String[] args) {
Student s1 = new Student();
s1.setName("小木","");
s1.setAge(-500);
System.out.println(s1.getName());
System.out.println(s1.getAge());
Student s2 = new Student();
s2.setName("Tina", "Lee");
s2.setAge(18);
System.out.println(s2.getName());
System.out.println(s2.getAge());
}// end of main(String[])
}// end of class Test
執行結果:
ERROR: name輸入錯誤,名字姓氏不得為空
ERROR: age輸入錯誤,年齡不可能為負數
unset
-1
TinaLee
18
可以看到物件s1因為亂帶參數,所以用setter在設定前被先檢查出來,可以進一步增加程式的穩定性。
Last updated
Was this helpful?