上篇文章--筆記20補充說明瞭前四點,這裡接著來說剩下的兩點。 要點如下: 5.訪問許可權修飾符可以修飾成員內部類 1).訪問許可權修飾符對內部類的訪問限制與外部類的一般成員遵循一樣的規則,具體請參考筆記10; 2).這裡涉及到的子類是外部類的子類; 6.訪問許可權修飾符可以修飾成員內部類的成員變數和成員 ...
上篇文章--筆記20補充說明瞭前四點,這裡接著來說剩下的兩點。
要點如下:
5.訪問許可權修飾符可以修飾成員內部類
1).訪問許可權修飾符對內部類的訪問限制與外部類的一般成員遵循一樣的規則,具體請參考筆記10;
2).這裡涉及到的子類是外部類的子類;
6.訪問許可權修飾符可以修飾成員內部類的成員變數和成員方法
1).成員內部類可由4種訪問許可權修飾符修飾,每種內部類的成員方法或變數也可由4種訪問許可權修飾符修飾,所以分16種情況來討論;
2).修飾類時涉及到的子類是外部類的子類;修飾內部類的成員方法或變數時涉及到的子類是成員內部類的子類;
3).構造方法的預設修飾符與類一致;
4).在外部類的不同包子類中創建protected修飾的內部類的對象時,會提示構造方法不可見,這時要為該內部類添加public修飾的構造方法;
作者: 蟬蟬
請尊重作者勞動成果,轉載請在標題註明“轉載”字樣,並標明原文鏈接:
http://www.cnblogs.com/chanchan/p/8281021.html
下麵詳細展開說明。
類Person中定義了4個成員內部類,分別由public、protected、預設、private修飾;並給這4個成員內部類分別添加4個成員方法,分別由public、protected、預設及private修飾。代碼如下:
1 public class InnerClassPu { 2 void printInCPuDef() { 3 System.out.println("public inner class:default"); 4 } 5 6 public void printInCPuPu() { 7 System.out.println("public inner class:public"); 8 } 9 10 protected void printInCPuPro() { 11 System.out.println("public inner class:protected"); 12 } 13 14 private void printInCPuPri() { 15 System.out.println("public inner class:private"); 16 } 17 } 18 19 protected class InnerClassPro { 20 void printInCProDef() { 21 System.out.println("protected inner class:default"); 22 } 23 24 public void printInCProPu() { 25 System.out.println("protected inner class:public"); 26 } 27 28 protected void printInCProPro() { 29 System.out.println("protected inner class:protected"); 30 } 31 32 private void printInCProPri() { 33 System.out.println("protected inner class:private"); 34 } 35 } 36 37 class InnerClass { 38 //訪問許可權修飾符修飾成員內部類的方法 39 void printInCDefDef() { 40 System.out.println("default inner class:default"); 41 } 42 43 public void printInCDefPu() { 44 System.out.println("default inner class:public"); 45 } 46 47 protected void printInCDefPro() { 48 System.out.println("default inner class:protected"); 49 } 50 51 private void printInCDefPri() { 52 System.out.println("default inner class:private"); 53 } 54 } 55 56 private class InnerClassPri { 57 void printInCPriDef() { 58 System.out.println("private inner class:default"); 59 } 60 61 public void printInCPriPu() { 62 System.out.println("private inner class:public"); 63 } 64 65 protected void printInCPriPro() { 66 System.out.println("private inner class:protected"); 67 } 68 69 private void printInCPriPri() { 70 System.out.println("private inner class:private"); 71 } 72 }
A.根據訪問許可權修飾符的特性,要驗證每種成員內部類的訪問許可權,需要分別在
1).外部類
2).與外部類同一個包的類
3).與外部類不同包的子類
4).與外部類不同包的其他類
這4種類中添加測試代碼。
註:
這裡是把成員內部類當成外部類的一個成員來看的,即,成員內部類是一個整體,對其他類而言它就是外部類的一個變數而已,所以這裡涉及到的子類是外部類的子類。
B.另,根據訪問許可權修飾符的特性,要驗證每種成員方法的訪問許可權,需要分別在
1).外部類
2).與成員內部類同一個包的類
3).與成員內部類不同包的子類
4).與成員內部類不同包的其他類
1>.其他類是外部類的子類
2>.其他類不是外部類的子類
這5種類中添加測試代碼。
註:
1].這裡要測試的是成員內部類的成員方法,所以對情況3而言,應該是成員內部類的子類,而不是外部類的子類;
又由於成員內部類位於外部類的內部,所以其子類是不可能位於其他包中的,所以第3種情況是不存在的。
2].由於成員內部類是外部類的一個成員,其可見性對“與其不同包的”“外部類的子類和非子類”是不一樣的,所以情況4要再細分成兩種情況。
綜合上面的A、B,下麵幾個圖是所有的測試代碼:
其中Person是外部類,TestMain是同包的類,GateMan是不同包的Person的非子類,Teacher是不同包的Person的子類。
1.Person內的測試:
由上圖可知:
所有成員內部類對外部類都可見;
所有成員內部類的所有成員方法對外部類都可見;
2.TestMain內的測試:
由上圖可知:
private修飾的成員內部類對與外部類同包的其他類是不可見的;
private修飾的成員內部類的所有成員方法對與內部類同包的其他類是不可見的;
public、protected及預設許可權的成員內部類對與外部類同包的其他類是可見的;
public、protected及預設許可權的成員內部類的public、protected及預設許可權的成員方法對與內部類同包的其他類是可見的;
public、protected及預設許可權的成員內部類的private許可權的成員方法對與內部類同包的其他類是可見的;
3.GateMan內的測試:
由上圖可知:
public修飾的成員內部類對與外部類不同包的非子類是可見的;
public修飾的成員內部類的public許可權的成員方法對與內部類不同包的非子類是可見的;
public修飾的成員內部類的其他許可權的成員方法對與內部類不同包的非子類是不可見的;
protected、預設及private修飾的成員內部類對與外部類不同包的非子類是不可見的;
protected、預設及private修飾的成員內部類的所有成員方法對與內部類不同包的非子類是不可見的---類不可見,其成員方法當然不可見;
4.Teacher內的測試:
註意28行,提示的錯誤與其他行都不一樣:
即,protected修飾的成員內部類InnerClassPro的構造方法是不可見的。
但第42行,即inCPro.printInCProPu();是沒有問題的,也就是說InnerClassPro是可以在Teacher里使用的。
為什麼會出現這樣的矛盾呢?
分析:
類Teacher與類Person不在同一個包里,但是其子類,所以protected修飾的內部類InnerClassPro對Teacher是可見的;
但類InnerClassPro沒有顯式創建構造方法,所以其預設的構造方法也是protected的;
對內部類InnerClassPro而言,類Teacher與其不在同一個包里,且不是其子類,所以,Teacher是看不到protected修飾的構造方法的;
因此就出現了上面的錯誤。
對策:
為類InnerClassPro添加構造方法,並聲明為public的,這樣就能保證Teacher能看到其構造方法並正確的創建InnerClassPro的對象了。
代碼如下:
protected class InnerClassPro { //構造方法為public public InnerClassPro() { } ... }
修改後,就不會出現上面的問題了,見下圖:
Teacher類里的完整測試代碼如下,就不再一一分析了:
下圖把16種情況的可見性依次列了出來,比較特殊的就是protected修飾的內部類InnerClassPro的public的成員方法,上面已詳細解釋說明過,不再贅述。(註:圖有點大,可點開查看)