java有四種訪問權限,它們各自的範圍以下圖所示java
當下列訪問修飾符修飾字段和方法時:測試
privatespa
任意位置的子類不能夠訪問從父類繼承的private字段和方法。這裏所說的訪問包括經過super關鍵字訪問。code
任意位置的對象不能經過「.」訪問對象的字段和方法。對象
publicblog
任意位置的子類能夠訪問從父類繼承的public字段和屬性。繼承
任意位置的對象能夠經過「.」訪問字段和屬性。內存
defaultio
當子類與父類在同一包下時,子類能夠訪問從父類繼承的default權限的字段和方法。編譯
當建立該對象的類與該對象所屬的類在同一包下時,能夠經過「.」訪問對象的字段和方法。
對於父類中的private、default權限的一些方法和字段,子類在必定程度上不能訪問它們,經過super訪問也不行。但子類對象初始化時,不只子類中聲明的成員變量分配了內存,父類的成員變量也都分配了內存,只是父類的成員不能被子類訪問罷了。可是咱們能夠經過子類從父類繼承的某些方法來操做這部分不能訪問的變量。
protected
上面的三種訪問權限都很好理解,protected的描述卻不是那麼清晰。
1)、當子類訪問從父類繼承的成員或方法時,無論是否在同一包均可以,在這個狀況下同public權限。
測試: p2包下的C2繼承p1包下的C1,C2在類中能夠直接訪問繼承來的方法
package p1; public class C1 { protected void fun() {} }
package p2; import p1.C1; public class C2 extends C1{ public void test() { fun(); } }
編譯正確:
2)當訪對象要用「.」訪問對象的protected字段(方法)時,分兩種狀況討論
i 若是訪問的這個方法(字段)是該對象的類本身定義的,且類型是protected。要求對象所在類與對象所屬類在同一包下。
package p1; public class C1 { protected void fun() {} }
package p2; import p1.C1; public class C2{ public void test() { new C1().fun(); } }
編譯報錯:(由於對象所在類p2.C2與對象所屬類p1.C1不在同一包下)
將C2放在包p1下後:
package p1; public class C2{ public void test() { new C1().fun(); } }
編譯正確:
ii 若是對象訪問的這個方法是該對象的類繼承而來的。要求對象所在類與該方法(字段)被最初被定義的類在同一包下。其實 i 是 ii 的特殊狀況。
測試: C2繼承C1的protected方法fun(),C3調用C2繼承的fun()方法,C3與C2在同一包下,編譯報錯。
package p1; public class C1 { protected void fun() {} }
package p2; import p1.C1; public class C2 extends C1{
}
package p2; public class C3{ public void test() { C2 c2 = new C2(); c2.fun(); } }
編譯結果:
測試:將上面的示例改變一下,C3放到C1的包下,編譯經過。
package p1; import p2.C2; public class C3{ public void test() { C2 c2 = new C2(); c2.fun(); } }
編譯結果:
protected總結:當在子類內部訪問從父類繼承而來的protected字段(方法)時,沒有包限制。當對象經過「.」訪問字段(方法)時,被protected修飾的方法(字段)的可見範圍是,該字段(方法)被定義的類所在的包。
本文我的編寫,水平有限,若有錯誤,懇請指出,歡迎討論分享。