<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                [TOC] ***** # 17.1 內部類概述 Java語言中允許在一個類(或方法、代碼塊)的內部定義另一個類,后者稱為“內部類”,封裝它的類稱為“外部類”。內部類與外部類之間存在邏輯上的隸屬關系,內部類一般只用在封裝它的外部類或代碼塊中使用。 ## 17.1.1 內部類的作用 內部類的作用如下: 1. 封裝。將不想公開的實現細節封裝到一個內部類中,內部類可以聲明為私有的,只能在所在外部類中訪問。 2. 提供命名空間。靜態內部類和外部類能夠提供有別于包的命名空間。 3. 便于訪問外部類成員。內部類能夠很方便訪問所在外部類的成員,包括私有成員也能訪問。 ## 17.1.2 內部類的分類 內部類的分類如圖17-1所示,按照內部類在定義的時候是否給它一個類名,可以分為:有名內部類和匿名內部類。有名內部類又按照作用域不同可以分為:局部內部類和成員內部類,成員內部類又分為:實例內部類和靜態內部類。 ![](https://box.kancloud.cn/6700bb0988a36f93e8cc4f2df9be78b3_809x628.jpg) # 17.2 成員內部類 成員內部類類似于外部類的成員變量,在外邊類的內部,且方法體和代碼塊之外定義的內部類。 ## 17.2.1 實例內部類 實例內部類與實例成員類似,可以聲明為公有級別、私有級別、默認級別或保護級別,即4種訪問級別都可以,而外部類只能聲明為公有或默認級別。 **實例內部類示例代碼如下:** ``` //Outer.java文件 package no_17; //外部類 public class Outer { // 外部類成員變量 private int x = 10; // 外部類方法 private void print() { System.out.println("調用外部方法..."); } // 測試調用內部類 public void test() { Inner inner = new Inner(); inner.display(); } // 內部類 class Inner { // 內部類成員變量 private int x = 5; // 內部類方法 void display() { // 訪問外部類的成員變量x System.out.println("外部類成員變量 x = " + Outer.this.x); // 訪問內部類的成員變量x System.out.println("內部類成員變量 x = " + this.x); System.out.println("內部類成員變量 x = " + x); // 調用外部類的成員方法 Outer.this.print(); print(); //8 } } } ``` 如果內部類和外部類它們的成員命名沒有沖突情況下,在引用外部類成員時可以不用加“外部類名.this”,如代碼第8行的print()方法只有外部類中定義,所以可以省略Outer.this。 **測試內部HelloWorld代碼如下:** ``` //Outer.java文件 package no_17; public class HelloWorld { public static void main(String[] args) { // 通過外部類訪問內部類 Outer outer = new Outer(); outer.test(); System.out.println("-------直接訪問內部類------"); // 直接訪問內部類 Outer.Inner inner = outer.new Inner(); //2 inner.display(); //3 } } ``` 通常情況下,使用實例成員內部類不是給外部類之外調用使用的,而是給外部類自己使用的。但是一定要在外部類的之外訪問內部類,Java語言也是支持的,見代碼第②行內部類的類型表示“外部類.內部類”,實例化過程是先實例化外部類,再實例化內部類,outer對象是外部類實例,outer.new Inner()表達式實例化內部類對象。 另外,HelloWorld與內部類Inner在同一個包中,內部類Inner和它的方法display()訪問級別都是默認的,它們對于在同一包中HelloWorld是可見的。 > **提示** 內部類編譯成功后生成的字節碼文件是“外部類$內部類.class”。 ## 17.2.2 靜態內部類 靜態內部類與靜態成員類似,在聲明的時候使用關鍵字static修飾。靜態內部類只能訪問外部類靜態成員,所以靜態內部類使用的場景不多。但可以提供有別于包的命名空間。 **示例代碼如下:** ``` //Outer.java文件 package no_17; //外部類 public class View { // 外部類實例變量 private int x = 20; // 外部類靜態變量 private static int staticX = 10; // 靜態內部類 static class Button { // 內部類方法 void onClick() { //訪問外部類的靜態成員 System.out.println(staticX); //不能訪問外部類的非靜態成員 // System.out.println(x); //編譯錯誤 } } } ``` 上述代碼第③行定義了靜態內部類Button,在靜態內部類中可以訪問外部類的靜態成員,見代碼第⑤行。但是不能訪問非靜態成員,見代碼第⑥行試圖訪問外部類的x實例變量,會發生編譯錯**誤。 測試內部HelloWorld代碼如下:** ``` //HelloWorld.java文件 package com.a51work6; public class HelloWorld { public static void main(String[] args) { // 直接訪問內部類 View.Button button = new View.Button(); button.onClick(); } } ``` 從代碼View.Button button = new View.Button()可見,在聲明靜態內部時采用“內部類.靜態內部類”形式,實例化也是如此形式。 > **提示** 如果不看代碼或文檔,View.Button形式看起來像是View包中的Button類,事實上它是View類中靜態內部類Button。View.Button形式客觀上能夠提供有別于包的命名空間,View相關的類集中管理起來,View.Button可以防止命名沖突。 # 17.3 局部內部類 局部內部類就是在方法體或代碼塊中定義的內部類,局部內部類的作用域僅限于方法體或代碼塊中。 局部內部類訪問級別只能是默認的,不能使用public、private和protected修飾。局部內部類也不能是靜態,即不能使用static修飾。局部內部類可以訪問外部類所有成員。 **示例代碼如下:** ``` ~~~ //Outer.java文件 package com.a51work6; //外部類 public class Outer { // 外部類成員變量 private int value = 10; // 外部類方法 public void add(final int x, int y) { //1 //局部變量 int z = 100; // 定義內部類 class Inner { //2 // 內部類方法 void display() { int sum = x + z + value; //3 System.out.println("sum = " + sum); } } // Inner inner = new Inner(); // inner.display(); //聲明匿名對象 new Inner().display(); //4 } } ~~~ ``` 上述代碼在add方法中定義了局部內部類,見代碼第②行,在內部類中代碼第③行訪問了外部類成員變量value、方法參數x和方法局部變量z,其中方法參數應該聲明為final的,見代碼第①行x參數是final的。 > **提示** 代碼第④行new Inner().display()是實例化Inner對象后馬上調用它的方法,沒有為Inner對象分配一個引用變量名,這種寫法稱為“匿名對象”。匿名對象適合只運行一次情況下。匿名對象寫法使代碼變得簡潔,但是給初學者閱讀代碼帶來了難度。 **測試內部HelloWorld代碼如下:** ``` //HelloWorld.java文件 package com.a51work6; public class HelloWorld { public static void main(String[] args) { Outer outer = new Outer(); outer.add(100, 300); } } ~~~ ``` # 17.4 匿名內部類 匿名內部類是沒有名字的內部類,本質上是沒有名的局部內部類,具有局部內部類所有特征。例如:可以訪問外部類所有成員。如果匿名內部類在方法中定義,它所訪問的參數需要聲明為final的。 **下面通過示例介紹一下匿名內部類。有如下一個View類:** ~~~ //View.java文件 package com.a51work6; //外部類 public class View { public void handler(OnClickListener listener) { ① listener.onClick(); } } ~~~ 代碼第①行中handler方法需要一個實現OnClickListener接口的參數。OnClickListener接口代碼如下: ~~~ //OnClickListener.java文件 package com.a51work6; public interface OnClickListener { void onClick(); } ~~~ 接口中只有一個onClick()方法。使用匿名內部類的示例代碼如下: ~~~ //HelloWorld.java文件 package com.a51work6; public class HelloWorld { public static void main(String[] args) { View v = new View(); //1 // 方法參數是匿名內部類 v.handler(new OnClickListener() { //2 @Override public void onClick() { System.out.println("實現接口的匿名內部類..."); } }); //繼承類的匿名內部類 Figure f = new Figure() { //3 @Override public void onDraw() { System.out.println("繼承類的匿名內部類..."); } }; //具體類作為內部類 Person person = new Person("Tony", 18) { //4 @Override public String toString() { return "匿名內部類.實現 " + " Person[name=" + name + ", age=" + age + "]"; } }; //打印過程自動調用person的 toString()方法 System.out.println(person); } } ~~~ 在HelloWorld的main方法中,代碼第①行是實例化View對象,代碼第②行是調用它的handler方法,該方法需要一個實現OnClickListener接口的參數,new OnClickListener() {… }表達式是實際參數,它就是匿名內部類。表達式中OnClickListener是要實現的接口或要繼承的類,new是為匿名內部類創建對象,()是調用構造方法,{… }是類體部分。 代碼第③行是在賦值時候使用匿名內部類,其中Figure是14.1.2節使用過的抽象類。匿名內部類實現了它的抽象方法onDraw()。 代碼第④行也是在賦值時候使用匿名內部類,其中Person是13.4.2節使用過的具體類,匿名內部類覆蓋了toString()方法。它有個兩個參數的構造方法,匿名內部類使用了這個構造方法。 匿名內部類通常用來實現接口或抽象類的,很少覆蓋具體類。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看