標籤:htm 修飾符 特性 alt 問題 tar color 其他 bubuko
修正:原文章有點錯誤,主要是關於成員內部類的子類的問題。
由於本人認知局限,想當然的認為內部類的子類也應該是內部類,其實不然,關於內部類的繼承的知識點會在筆記22中說明。
改動的地方主要有:
1).追加了“ 5.InnerClassChild2與內部類不同包”,測試了內部類的成員方法在與成員內部類不同包的子類中的可見度。
2).修改了最後的圖片,public的內部類的protected許可權的成員方法的可見度為:同包的類及不同包的內部類的子類
上篇文章--筆記20補充說明了前四點,這裡接著來說剩下的兩點。
要點如下:
5.存取權限修飾符可以修飾成員內部類
1).存取權限修飾符對內部類的訪問限制與對外部類的一般成員遵循一樣的規則,具體請參考筆記10;
2).這裡涉及到的子類是外部類的子類;
6.存取權限修飾符可以修飾成員內部類的成員變數和成員方法
1).成員內部類可由4種存取權限修飾符修飾,每種內部類的成員方法或變數也可由4種存取權限修飾符修飾,所以分16種情況來討論;
2).修飾類時涉及到的子類是外部類的子類;修飾內部類的成員方法或變數時涉及到的子類是成員內部類的子類;
3).構造方法的預設修飾符與類一致;
4).在外部類的不同包子類中建立protected修飾的內部類的對象時,會提示構造方法不可見,這時要為該內部類添加public修飾的構造方法;
5).內部類的成員方法的可見度,由內部類的修飾符及成員方法的修飾符共同決定;
蟬蟬
請尊重作者勞動成果,如需轉載請在標題註明“轉載”字樣,並標明原文連結:
http://www.cnblogs.com/chanchan/p/8337173.html
PS:轉成日記後怎麼沒辦法轉回隨筆?只好重發一次了
下面詳細展開說明。
類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).與成員內部類不同包的成員內部類的子類(更正.2018.1.23)
4).與成員內部類不同包的其他類
1>.其他類是外部類的子類
2>.其他類不是外部類的子類
這5種類中添加測試代碼。
註:
1].這裡要測試的是成員內部類的成員方法,所以對情況3而言,應該是成員內部類的子類,而不是外部類的子類;
又由於成員內部類位於外部類的內部,所以其子類是不可能位於其他包中的,所以第3種情況是不存在的。(成員內部類的子類可以位於其他包中 2018.1.24)
2].由於成員內部類是外部類的一個成員,其可見度對“與其不同包的”“外部類的子類和非子類”是不一樣的,所以情況4要再細分成兩種情況。
綜合上面的A、B,A中的1、2、3、4分別與B中的1、2、4.1、4.2範圍一樣,再追加B中3的測試代碼即可,見下面第5條。(追加:2018.1.24)
下面幾個圖是所有的測試代碼:
其中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不在同一個包裡,但為Person的子類,所以protected修飾的內部類InnerClassPro對Teacher是可見的;
但類InnerClassPro沒有顯式建立構造方法,所以其預設的構造方法也是protected的;
對內部類InnerClassPro而言,類Teacher與其不在同一個包裡,且不是其子類,所以,Teacher是看不到protected修飾的構造方法的;
因此就出現了上面的錯誤。
對策:
為類InnerClassPro添加構造方法,並聲明為public的,這樣就能保證Teacher能看到其構造方法並正確的建立InnerClassPro的對象了。
代碼如下:
protected class InnerClassPro { //構造方法為public public InnerClassPro() { } ... }
修改後,就不會出現上面的問題了,見:
Teacher類裡的完整測試代碼如下,就不再一一分析了:
5.InnerClassChild2與內部類不同包
InnerClassChild2要繼承一個成員內部類,如所示,只有public修飾的成員內部類在其他包中可見,也就是說,只有public許可權的成員內部類能在其他包中有子類。
InnerClassChild2繼承了內部類Person.InnerClassPu, 如所示:
建立子類對象inCCh,成員方法printInCPuPu和printInCPuPro都是可見的;由於InnerClassChild2是子類,且不同包,所以父類中由public和protected修飾的成員方法都是可見的,預設及private修飾的成員方法不可見;
建立父類對象inCPu,只有成員方法printInCPuPu是可見的;
筆記10中也出現了這樣的現象,下面的一段摘自筆記10:
如果在與Person不同包的子類Teacher中定義了Teacher類對象,則通過該對象可以訪問和調用Person中public和protected修飾的成員變數和成員方法,default、private修飾的成員變數和成員方法都不可以訪問或調用;
如果定義了Person類對象,則通過該對象只可以訪問和調用Person中public修飾的成員變數和成員方法,protected、default、private修飾的成員變數和成員方法都不可以訪問或調用。
疑問:不明白為什麼會有這樣的差異。
總結:
通過上面的5步測試,可以看出:
1).存取權限修飾符修飾成員內部類及成員內部類的成員時,與修飾一般類的成員時遵循一樣的規則(見筆記10)。
2).內部類的成員方法的可見度,由內部類的修飾符及成員方法的修飾符共同決定。
附:
把16種情況的可見度依次列了出來,比較特殊的就是:
1).public修飾的內部類InnerClassPu 的 protected的成員方法;
2).protected修飾的內部類InnerClassPro 的 public的成員方法;
原因上面已詳細解釋說明過,不再贅述。
(註:圖有點大,可點開查看)
Java學習筆記21---內部類之對成員內部類的補充說明(二)(修正)