Java學習筆記21---內部類之對成員內部類的補充說明(二)

来源:https://www.cnblogs.com/chanchan/archive/2018/01/16/8281021.html
-Advertisement-
Play Games

上篇文章--筆記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的成員方法,上面已詳細解釋說明過,不再贅述。(註:圖有點大,可點開查看)

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 一、JavaScript(JS)定義: JavaScript一種直譯式腳本語言,是一種動態類型、弱類型、基於原型的語言。 JavaScript通常用來操作HTML頁面,響應用戶操作,驗證傳輸數據等。 jQuery和JavaScript有什麼關係?jQuery是由JS編寫的一個js庫。 JavaScr ...
  • //num為小寫金額,單位元 changeMoney(num) { if(isNaN(num))return ""; var strPrefix=""; if(num=1000000000000)return ""; var strOutput = ""; var strUnit = '仟佰拾億仟佰... ...
  • 在做微信二次開發的時候或者手機版網頁的時候有人想在接qq客服,下麵我就分享一下具體操作: 1,準備一個QQ號,可以是企業QQ,也可以是個人QQ。登錄網址:http://shang.qq.com/widget/consult.php 開通你的QQ通訊組件,一般登錄進去就算開通了。 2,複製如下QQ客服 ...
  • 委托模式顧名思義就是甲讓乙做事,但乙又讓丙做的,而甲是不知道的。 乙所具有的功能是很方便擴展的。 甲方是使用工具的: JiaFang.php 乙方是承接任務的: YiFang.php 丙方是真正做事的: BingFang.php 運行JiaFang.php,輸出結果 ...
  • Django2.0中URL的路由機制 路由是關聯url及其處理函數關係的過程。Django的url路由配置在settings.py文件中ROOT_URLCONF變數指定全局路由文件名稱。 Django的路由都寫在urls.py文件中的urlpatterns列表中,由path()或re_path()作 ...
  • 條款1:視C++為一個語言聯邦:C、Object-Oriented C++、Template C++、STLC++高效編程守則視情況而變化,取決於使用C++的哪一個部分 條款2:儘量以const,enum,inline替換#define1、對於單純的常量,最好以const對象或enums替代#def ...
  • 在日常工作中,我們往往會給前端(WEB端、IOS、Android)或者第三方提供介面,這個時候我們就需要給他們提供一份詳細的API說明文檔。但維護一份詳細的文檔可不是一件簡單的事情。首先,編寫一份詳細的文檔本身就是一件很費時費力的事情,另一方面,由於代碼和文檔是分離的,所以很容易導致文檔和代碼的不一... ...
  • PyCharm 社區版創建項目無法選擇Django等項目,只能選擇Python項目。 你在進行練習的時候為了方便,可以用過期了的PyCharm專業版在可用的30分鐘內創建社區版本不支持的項目,再用PyCharm社區版打開就可以了。適合新手。 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...