在說Java 三個特性之前,我們先了解一下什麼是面向對象,以及為什麼Java是面向對象的語言。
面向對象是區別於面向過程的一種編程的思想。我們可以通過這個例子冰箱裝大象的例子來了解一下面向對象與面向過程的區別。
想必通過這個例子,應該清楚了面向對象與面向過程的區別。 面向過程是指我們主要注重於每一階段的過程,而面向對象是指我們主要注重每一個動作的執行者。Java就是注重於動作的執行者,注重於編寫類,注重於代碼和功能復用的語言。
上面我們已經說到了Java是注重於類的編寫,那麼封裝自然也是對類的封裝。對類封裝有很多好處。
如何對一個類進行封裝,則需要根據這個類本身的客觀屬性與實際的需要。
比如一個MyTime類
public class MyTime{
public String date;
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//設置日期格式
date= df.format(new Date());
public String getDate() {
return date;
}
//
// public void setDate(String date) {
// this.date = date;
// }
}
顯然這個類是只提供了顯示系統的時間,不提供外部去修改系統時間的方法。這個也是根據類本身的客觀屬性而言,時間是固有不會人為改變的屬性,當然諸如此類的例子,還有很多。我們只是簡單舉例來表明我們該如何設計類的外部訪問方法。
在上面的代碼中,我們已經看到可以調用getData()方法對date進行訪問,但是date的修飾符是public ,換句話說,我們完全可以new 一個MyTime對象對date屬性進行修改和讀值,這就違背了我們封裝的初衷。所以,Java引入了不同的訪問權限來限定這件事情。在《Java編程思想》中講解了下述的訪問權限
public:接口訪問權限。也就是說public修飾的成員方法,屬性都是可以在任何地方所訪問的。
private: 你無法訪問 。也就說private修飾的成員方法,屬性 都是只能在這個類中被訪問,出了這個類以外的地方,你是無法訪問到這個類裡面的內容,這十分的有用,我們上面的例子代碼,因為是public修飾,所以會出現封裝不徹底的問題,如果我們的成員變量date用private修飾,那麼就會不出現上述的問題。
protected: 繼承訪問權限。在說到繼承訪問權限之前,我們思考這樣一個問題,我們有一個基類,是需要被繼承的。基類中的成員屬性,我們是希望能被繼承的類所訪問,那麼我們是可以把他設定成public,但是一旦這樣的話,除了這個繼承的類,其他類也會訪問到。這個顯然不是我們所期望的事情,所以Java引入protected修飾符,來表示所修飾的部分是能被派生的類所訪問的,同時他也能被同一包裡面的其他類所訪問。
所以,總結一下,如果我們是希望類中的方法和屬性能被所有類所訪問,就用public,如果只是能被繼承的類和同一包內的類所訪問就用protected,如果只是希望在當前類中所訪問,不能被其他任何類訪問就要用private。
在了解了封裝的具體含義和好處之後,我們就可以利用上面的訪問權限來對我們要向封裝的東西進行封裝,通過訪問權限來隱藏具體的實現,和提供外部訪問的接口。
public class Student {
private String name;
private String age;
private String handleName(String name){
return "I'm " + name;
}
private String handleAge(String age) {
return age + " 歲";
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = handleName(name);
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = handleAge(age);
}
}
在上面的例子中,我們對Student類進行了簡單的封裝,首先我們切斷了外部直接調用到name,age的可能,通過set和get方法來提供訪問到name,age的方法,同時,上面的例子中也體現出來了,在外部訪問方法不變的情況下,自己隨意修改內部的實現,我們首先編寫了只供類內部調用的Handle的方法,用Handle方法來修改name,age的顯示結果。這樣確保了修改顯示結果的方法只能自己調用,而且在外部訪問不變的情況下,根據需求修改內部的實現。這也是一個簡單的封裝例子。其調用的例子如下:student對象只能調用如下的內容,其他我們自己編寫的內容是無法調用的。
public class Test {
public static void main(String[] args) {
Student student = new Student();
student.setName("byhieg");
student.setAge("23");
System.out.println(student.getName() + " " + student.getAge());
}
}