前言:
我們平時做項目或是學習的時候,訪問修飾符用的最多的就是 public 和 private 兩種,對於這兩種訪問修飾符,稍有編程經驗的人都比較熟悉。但是另外兩種呢?protected 和 default 用的比較少,因此很多人對這兩種訪問修飾符的瞭解很模糊。可能很多人只記得下面這張圖,但是對訪問修飾符的關鍵作用“訪問控制”理解的還不夠深刻。
今天在溫故而知新的時候,對 protected 這個訪問修飾符有了一點兒新的理解,趁熱打鐵,就寫出來分享分享。
簡單敘述四種訪問修飾符的區別:
public:
在當前類中,凡是用public修飾的方法(類方法、實例方法),都可被其它類訪問(這個類可以在任何地方,同不同包無所謂)。同理,public修飾的屬性亦如此。
private:
在當前類中,凡是用private修飾的方法(類方法、實例方法),都是私有的,有且僅有該類自己可以訪問。屬性同理。
default:
使用default修飾的方法(類方法、實例方法),只可被“當前包中的類”訪問,其它包中的類無權訪問。屬性同理。
protected:
使用protected修飾的方法,在default的基礎上,還可被子孫類(直接子類、間接子類)訪問。屬性同理。
關於protected的一點兒新發現:
父類:
package parent_package;
public class Parent {
protected static void proStaMethod() {
}
protected void proMethod() {
}
}
子類:
package child_package;
import parent_package.Parent;
public class Child extends Parent {
public void test() {
// 類名訪問
Parent.proStaMethod();
// 對象訪問
Parent parent = new Parent();
parent.proStaMethod();
// this訪問
this.proStaMethod();
this.proMethod();
// super訪問
super.proStaMethod();
super.proMethod();
}
}
我把子類訪問父類 protected 方法的所有途徑都列出來了,有一個地方非常有意思:
“對象訪問”的時候只能訪問到 Parent 類受保護的”類方法“ proStaMethod() ,並不能訪問到受保護的”實例方法“ proMethod() 。
有沒有人對此感到驚訝呢?如果按我們一開始的說法,子類中是可以訪問到父類中受保護的實例方法的。在這裏,爲什麼“ this 訪問”和“ super 訪問”都可以訪問到實例方法,唯獨“對象訪問”的形式不行呢?
我的解釋:
類比現實生活,我們拜訪別人的時候,有兩種途徑:私下拜訪、公開拜訪。私下拜訪就會有人情在裏面;公開拜訪就更傾向於公開平等,私人關係就擺在了次要的位置上。
“ this 訪問”和“ super 訪問”就好比是私下拜訪:子類私下拜訪父類,就明顯的體現出“父子關係”,父類和子類處於不同的包,按理說,父類對子類所在的包是排斥的,但是由於“親情”,父類讓子類繼承了自己保護的方法(相當於從父類那裏 copy 一份),並且還讓子類有權訪問自己保護的方法,“ this 訪問”就是子類訪問繼承自父類的方法(已經是自己的了),“ super 訪問”就是去父類那裏,訪問屬於父類的方法。
”類名訪問“和”對象訪問“就好比公開拜訪:這時候,”父子關係“就要拋開,公開平等的規則最重要!既然父類對子類在所的包是排斥的,那麼,父類到子類這兒來了以後,父類保護的方法肯定是誰都不讓訪問的(包括子類)。這也就解釋了子類爲什麼不能通過”對象訪問“的形式訪問父類的保護方法了。