天天看點

Java基礎篇:封裝

介紹

面向對象最基本的特征,把真實世界的某些物體包成對象,裡面的資訊不對外公開,隻公開某些特定方法讓别人使用,内部的屬性與邏輯都隐藏起來,不讓人直接使用,也不需要讓别人直接使用,就是所謂的

封裝

設想一個例子,

提款機

,你不知道它裡面還有多少錢,也不知道内部的運做,不知道哪家公司生産的機器,但你還是會去使用他提供的方法:

查詢餘額

提款

。因為他隻開放這兩個方法給一般人使用,你要使用這兩個方法需要帶入的參數是提款卡及密碼,就可以完成你的需求

class ATM {
    private BigDecimal 剩餘金額;

    private boolean 身份驗證(Object 提款卡, String 密碼) {
        // 驗證邏輯
        // 通過 傳回 true
    }

    private void 吐鈔() {
        // 哒哒哒哒哒哒
    }

    public void 提款(Object 提款卡, String 密碼) {
        if (身份驗證(提款卡, 密碼) == true)
            吐鈔();
    }

    public BigDecimal 查詢餘額(Object 提款卡, String 密碼) {
        // 查詢資料庫餘額 0
        if (身份驗證(提款卡, 密碼) == true)
            return 剩餘金額;
        else
            return BigDecimal.ZERO;
    }
}           

當然實際上更為複雜且嚴密(而且我對提款機不熟),但在怎麼複雜,使用上一般使用者隻要知道使用哪些公開的方法就好(雖然不熟但我會領錢、查餘額),剩下的就是設計這個類别的設計師要負責的工作

常用修飾符 private 、 public

private 私有

private

是屬性隐藏會普遍使用的修修飾符,開放權限最低,隻有目前類中能夠存取

public 公開

private

相反,

public

是任何人都可以調用,通常用來表示這個方法可以供大家通路,一個

public

的方法内可以調用多個 private 的方法來實作需要的功能

Getter 與 Setter

為了屬性隐藏,我們常把重要屬性設為

private

,要供别人(甚至自己)存取的時候,通常會利用

getter()

setter()

這種對外公開方法間接的存取。

來看個例子,學生類的屬性有姓名、年齡,提供

setter

getter

方法

public class Student {

    private String name;
    private int age = -1;

    public void setName(String name) {
        if (name == null || name.trim().length() == 0) {
            System.out.println("ERROR: 名字不能為空!");
        } else {
            this.name = name;
        }
    }

    public void setAge(int a) {
        if (a < 0) {
            System.out.println("ERROR: 年齡不能為負數!");
        } else {
            this.age = a;
        }
    }

    public String getName() {
        return name == null ? "無名氏" : this.name;
    }

    public int getAge() {
        return age;
    }

    @Override
    public String toString() {
        return "Student{" +
                "名字:'" + this.getName() + '\'' +
                ", 年齡:" + this.getAge() +
                '}';
    }
}           

這是常見的設計方法,成員屬性的部份都設為 private,而公開了

setName()

setAge()

讓别人調用來設定

name

age

的值,這就是通過公開方法間接的設定隐藏的屬性值,好處是我這樣寫可以在設定屬性值前先做一些前處理(以上述代碼來說就是檢查參數的合法性)。

getter

的部份,也公開了兩個方法可以讓别人存取到内部隐藏的屬性,以

getName()

來說,可以在回傳出去前多做一步處理(這裡簡單空判斷) ,這樣的設計方式是常見且容易維護的。

測試代碼

public class TestStudent {
    public static void main(String[] args) {

        Student s1 = new Student();
        s1.setName("源十天狗");
        System.out.println("s1設定年齡為-500");
        s1.setAge(-500);
        System.out.println("列印s1:==>"+ s1.toString());

        Student s2 = new Student();
        System.out.println("s2不設定名字");
        s2.setName(null);
        s2.setAge(18);

        System.out.println("列印s2:==>"+ s2.toString());

    }
}           

輸出

s1設定年齡為-500
ERROR: 年齡不能為負數!
列印s1:==>Student{名字:'源氏舔狗', 年齡:-1}
s2不設定名字
ERROR: 名字不能為空!
列印s2:==>Student{名字:'無名氏', 年齡:18}           

可以看到對象 s1 因為亂傳參數,是以在

setter

被設定前被先檢查出來,可以進一步增加程式的穩定性