1. 程式人生 > >java的封裝性

java的封裝性

目的

限制在類的外部對類內部成員進行訪問,只通過公共介面來訪問類的成員資料。
遮蔽細節:這是程式設計的基本思想,便於程式功能的擴充套件和程式的維護。

封裝類

大多數變數都是私有的,變數通過他們自己類的方法修改,一個類只向其它類公開一部分成員(通常是方法)作為介面;
若變數或方法為公有,它就是介面的一部分,其它類可以訪問它;若為私有,它是實現的一部分,只有類自己的成員可以訪問它。

訪問控制符

Java通過訪問控制來實現封裝性,訪問控制通過4個訪問修飾符實現。

default(預設)
public(公共)
protected(保護)
private(私有)

訪問修飾符限定了被修飾者的可見性。

類的訪問控制

類的許可權有兩種:

預設(修飾符為空),該類只能被自身所在的包中的類使用。
public,該類能被所有包中的類使用。

如果在一個源程式檔案中,聲明瞭若干個類的話,只能有一個類的許可權關鍵字是public。這個類的名字應該和程式檔案同名,main方法也應該在這個類中,否則程式無法執行。

public:在任何地方,只要能訪問到該類,即可訪問到該成員。
protected:該成員允許同一個包或該類的擴充套件子類訪問。 
預設:該成員只能由同一個包中的其它類訪問。
private:類中的該成員只能由該類自己的成員呼叫,而無法被該類以外的其它類訪問。

宣告區域性變數不能包含訪問許可權修飾符,否則編譯時將檢查出錯。

封裝性的設計原則

基本思想:提供對外的通訊方式,封裝內部的實現機制。

增加內部實現部分的可替換性;
減小類之間的耦合關係,方便模組劃分;
容易保證類內部資料間的一致性,從而提高軟體的可靠性。

基本原則:

類常常是public;
成員變數常常是private;
構造方法一般是public;
方法“getter”與“setter”是 public;
其它方法需要根據實際的需要而定。

私有化構造方法

這是一種設計模式——單例模式

類的封裝性不止體現在對屬性的封裝,還可以對方法進行封裝,這裡我們看一下對構造方法的封裝。

對屬性封裝可以防止其他類隨意修改一個類的成員變數,那為什麼要對構造方法進行封裝?

我們知道物件在例項化時會呼叫類的構造方法,如果將構造方法私有化(隱藏起來),則外部無法例項化物件,而此時若在內部例項化物件,並提供一個方法將該例項返回出去,則其他類中也可以獲取到這個例項,這樣可以保證一個類在記憶體中物件的唯一性。

總體來說,想要保證物件的唯一性,要做到:

1.避免其他類過多的建立該類物件,先禁止其他類建立該類物件

2.為了讓其他類訪問到該類物件,只好在本類中例項化一個物件

3.為了方便其他類對自定義物件的訪問,可以對外提供一些訪問方式

對應於程式碼實現:

1.構造方法私有化

2.在類中建立一個本類物件

3.提供方法可以獲取到該物件

程式碼:

class Singleton{  
    private Singleton(){        //構造方法例項化  
    }  
    public void print(){  
        System.out.println("Hello World!");  
    }  
}  
public class SingletonDemo{  
    public static void main(String[] args){  
        Singleton s1 = null;  //宣告物件  
    }  
}  

此時,外部SingletonDemo類只能宣告物件,無法例項化物件,所以我們需要在Singleton類內部例項化物件。

class Singleton{  
    Singleton instance = new Singleton();  //在內部例項化物件  
    private Singleton(){        //構造方法例項化  
    }  
    public void print(){  
        System.out.println("Hello World!");  
    }  
}  
public class SingletonDemo{  
    public static void main(String[] args){  
        Singleton s1 = null;  //宣告物件  
    }  
}  

此時要考慮外部SingletonDemo類如何獲取內部生成的instance物件,這樣外部就可以直接通過該物件例項化了。
如果在沒有例項化物件的時候獲得instance物件,則要將instance宣告為static型別,因為static宣告的變數,可以直接通過類名.屬性進行訪問 。

class Singleton{  
    static Singleton instance = new Singleton(); //在內部例項化物件  
    private Singleton(){        //構造方法例項化  
    }  
    public void print(){  
        System.out.println("Hello World!");  
    }  
}  
public class SingletonDemo{  
    public static void main(String[] args){  
        Singleton s1 = null;  //宣告物件  
        s1 = Singleton.instance;  
        s1.print();  
    }  
}  

輸出結果:
Hello World!
此時結果已經出來,但是正常情況下,屬性應該要進行封裝,所以我們將instance封裝後,並提供getInstance()方法對外返回instance程式碼如下:

程式碼:

class Singleton{  
    private static Singleton instance = new Singleton();  //在內部例項化物件  
    public static Singleton getInstance(){  
        return instance;  
    }  
    private Singleton(){        //構造方法例項化  
    }  
    public void print(){  
        System.out.println("Hello World!");  
    }  
}  
public class SingletonDemo{  
    public static void main(String[] args){  
        Singleton s1 = null;  //宣告物件  
        s1 = Singleton.getInstance();  
        s1.print();  
    }  
}  

這樣完整的程式碼就寫出來了,而這程式碼就是Java中的單例設計模式的一種寫法
如果不希望一個類產生很多物件,就需要使用單例設計模式,這種模式的應用有很多,比如印表機在列印的時候只能建立一個列印例項,不然會造成記憶體浪費邏輯混亂;又如如在Windows中就只能開啟一個工作管理員。如果不使用單例機制對視窗物件進行唯一化,將彈出多個視窗,如果這些視窗顯示的內容完全一致,則是重複物件,浪費記憶體資源;如果這些視窗顯示的內容不一致,則意味著在某一瞬間系統有多個狀態,邏輯混亂。
單例模式的核心是構造方法的私有化(即在入口處限制了物件的例項化),之後在類的內部例項化物件,並通過靜態方法返回例項化物件的引用。