常見的訪問修飾符的使用權限分類:ide
類內部 | 本包 | 子類 | 外部包 | |
public | √ | √ | √ | √ |
protected | √ | √ | √ | × |
default (缺省) | √ | √ | × | × |
private | √ | × | × | × |
其中,對於類的修飾,只能是 public 或者缺省。post
對於方法和成員變動的修飾,public是最寬容的,比較難理解的是projected。spa
顯而易見的,對於同一個包裏面,和子類裏面,能夠直接調用protected修飾的方法。可是當子類不在同一個包中時,就須要注意了,能夠帶着以下幾個問題往下看:code
同一個包中, 子類對象能訪問父類的 protected 方法嗎? (能夠)對象
不一樣包下, 在子類中建立該子類對象能訪問父類的 protected 方法嗎?(能夠)blog
不一樣包下, 在子類中建立父類對象能訪問父類的 protected 方法嗎?(不能夠)ci
不一樣包下, 在子類中建立另外一個子類的對象能訪問公共父類的 protected 方法嗎?(不能夠)編譯器
父類 protected 方法加上 static 修飾符又會如何呢?編譯
package a1;
public class ProTest { protected void say(){ System.out.println("Proteced say"); } public void laugh(){ System.out.println("Protest laugh"); } }
對於不在同一個包的類:是沒法訪問protected修飾的say()方法的,但能夠訪問 laugh();table
對於子類若不在同一個包中,只能在本類中訪問父類的protected方法
不一樣包下,在子類中經過父類引用不能夠訪問其 protected 方法
package a2; import a1.ProTest; public class Tester { public static void main(String arg[]){ ProTest p = new ProTest(); p.laugh();//ok p.say();//編譯器提示沒法訪問 } }
package a2; public class Effect extends ProTest { public static void main(String args[]){ ProTest p = new ProTest();
Effect e = new Effect() e.say();// ok
p.say();//編譯不經過,不管是建立 ProTest 對象仍是經過多態建立 Effect 對象, 只要 ProTest 引用, 則不可訪問, 編譯器會提示錯誤。
}
}
這時,對於同在a2包中的其它類,對於子類和父類的say()方法均不能調用,
靜態方法直接經過類名訪問
不管是否同一個包,在子類中都可直接訪問
package a2; import a1.ProTest; public class Tester { public static void main(String arg[]){ ProTest p = new ProTest(); Effect effect = new Effect(); p.say(); //編譯不經過 ,可是父類中若是是靜態的方法,那麼能夠訪問 effect.say(); // 編譯不經過 } }
若是子類覆蓋了say()方法,則能夠在a2包中使用子類的say()方法:
package a2; import a1.ProTest; public class Effect extends ProTest { @Override public void say(){ System.out.println("effect say"); } }
package a2; import a1.ProTest; public class Tester { public static void main(String arg[]){ Effect effect = new Effect(); ProTest p = new Effect(); effect.say(); // 輸出 effect say p.say(); //編譯錯誤 ,若是把父類放到同一個a2包下,則這裏能夠調用,可是輸出的是effect say } }