Roger Tu

          A simple boy living a simple life in every simple day...

             ::  :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
            7 隨筆 :: 0 文章 :: 19 評(píng)論 :: 0 Trackbacks

          簡(jiǎn)單的說(shuō),內(nèi)部(inner)類(lèi)指那些類(lèi)定義代碼被置于其它類(lèi)定義中的類(lèi);而對(duì)于一般的、類(lèi)定義代碼不嵌套在其它類(lèi)定義中的類(lèi),稱(chēng)為頂層(top-level)類(lèi)。對(duì)于一個(gè)內(nèi)部類(lèi),包含其定義代碼的類(lèi)稱(chēng)為它的外部(outer)類(lèi)。

          1          Static member class(靜態(tài)成員類(lèi))

          類(lèi)聲明中包含“static”關(guān)鍵字的內(nèi)部類(lèi)。如以下示例代碼,

          Inner1/Inner2/Inner3/Inner4就是Outer的四個(gè)靜態(tài)成員類(lèi)。靜態(tài)成員類(lèi)的使用方式與一般頂層類(lèi)的使用方式基本相同。


          public class  Outer{
              
          //just like static method, static member class has public/private/default access privilege levels
              
              
          //access privilege level: public 
              public static class Inner1 {
                  
          public Inner1() {
                      
          //Static member inner class can access static method of outer class
                      staticMethod();    
                      
          //Compile error: static member inner class can not access instance method of outer class
                      
          //instanceMethod();  
                  }
              }
              
              
          //access privilege level: default 
              static class Inner2 {
                  
              }
              
              
          //access privilege level: private 
              private static class Inner3 {
                  
          //define a nested inner class in another inner class 
                  public static class Inner4 {    
                  }
              }

              
          private static void staticMethod() {
                  
          //cannot define an inner class in a method
                  /*public static class Inner4() {
                  }
          */
              }
              
              
          private void instanceMethod() {
                  
          //private static member class can be accessed only in its outer class definition scope
                  Inner3 inner3 = new Inner3();
                  
          //how to use nested inner class
                  Inner3.Inner4 inner4 = new Inner3.Inner4();
              }
          }

          class Test {
              Outer.Inner1 inner1 
          = new Outer.Inner1();
              
          //Test and Outer are in the same package, so Inner2 can be accessed here
              Outer.Inner2 inner2 = new Outer.Inner2(); 
              
          //Compile error: Inner3 cannot be accessed here
              
          //Outer.Inner3 inner3 = new Outer.Inner3(); 
          }

           


          1.1      靜態(tài)成員類(lèi)特性

          • 靜態(tài)成員類(lèi)可訪(fǎng)問(wèn)外部類(lèi)的任一靜態(tài)字段或靜態(tài)方法
          • 像靜態(tài)方法或靜態(tài)字段一樣,靜態(tài)成員類(lèi)有public/private/default權(quán)限修飾符

          1.2      靜態(tài)成員類(lèi)約束

          • 靜態(tài)成員類(lèi)不能與外部類(lèi)重名
          • 像外部類(lèi)的靜態(tài)方法一樣,不能直接訪(fǎng)問(wèn)外部類(lèi)的實(shí)例字段和實(shí)例方法
          • 靜態(tài)成員類(lèi)只能定義于外部類(lèi)的頂層代碼或外部類(lèi)其它靜態(tài)成員類(lèi)的頂層代碼中(嵌套定義);不能定義于外部類(lèi)的某個(gè)函數(shù)中。

          1.3      新增語(yǔ)法

              如示例代碼所示,可以以“OuterClass.InnerClass”的方式來(lái)引用某個(gè)內(nèi)部類(lèi)。

          1.4      什么時(shí)候使用靜態(tài)成員類(lèi)

          BA的輔助類(lèi),且只為A所用時(shí),可將B定義為A的靜態(tài)成員類(lèi)。例如JDK中的LinkedList類(lèi)就有Entry靜態(tài)成員類(lèi):

          public class LinkedList<E> extends AbstractSequentialList<E> 
             …;
             
          private static class Entry<E> {
              E element;
              Entry
          <E> next;
              Entry
          <E> previous;

              Entry(E element, Entry
          <E> next, Entry<E> previous) {
                  
          this.element = element;
                  
          this.next = next;
                  
          this.previous = previous;
              }
              }
              …;
          }

             顯然,Entry用來(lái)表示LinkedList中的一個(gè)結(jié)點(diǎn),只被LinkedList自身使用。

           

          2          Member class(成員類(lèi))

          一個(gè)靜態(tài)成員類(lèi),若去掉“static”關(guān)鍵字,就成為成員類(lèi)。如下示例代碼,Inner1/Inner2/Inner3/Inner4就是Outer的四個(gè)成員類(lèi)
           

          public class Outer {
              
          //just like instance method, member class has public/private/default access privilege levels
              private int data;
              
              
          //access privilege level: public 
              public class Inner1 {
                  
          private int data;
                  
          private int data1;
                  
          public Inner1() {
                      
          //member class can access its outer class' instance field directly
                      data1 = 1;
                      
          //itself data field
                      data = 1;
                      
          //its outer class instance field
                      Outer.this.data = 1;
                  }
              }
              
              
          //access privilege level: default
              class Inner2 {
                  
          //can not define static filed, method, class in member class
                  
          //static int j = 1;
                  
                  
          //but, "static final" compound is allowed 
                  static final int CONSTANT = 1;
              }
              
              
          //access privilege level: private 
              private class Inner3 {
                  
          public class Inner4 {
                      
                  }
              }
              
              
          //in fact, Inner5 is not a member class but a static member class
              interface Inner5 {
              }
              
              
          private static void staticMethod() {
                  
          //can not create a member class instance directly in outer class' static method
                  
          //Inner1 inner1 = new Inner1();
              }
              
              
          private void instanceMethod() {
                  
          //can create a member class instance in outer class' instance method
                  Inner1 inner1 = new Inner1();
              }
          }

          class Test {
              
          public Test() {
                  
          //cannot create member class instance directly in class other than outer class
                  
          //Outer.Inner2 inner2 = new Outer.Inner2();
                  
                  
          //create a member class instance outside it's outer class
                  Outer outer = new Outer();
                  Outer.Inner1 inner1 
          = outer.new Inner1();
              }
          }

           

           

          2.1      成員類(lèi)特性

          ·        類(lèi)似于外部類(lèi)的實(shí)例函數(shù),成員類(lèi)有public/private/default權(quán)限修飾符

          ·        一個(gè)成員類(lèi)實(shí)例必然所屬一個(gè)外部類(lèi)實(shí)例,成員類(lèi)可訪(fǎng)問(wèn)外部類(lèi)的任一個(gè)實(shí)例字段和實(shí)例函數(shù)。

          2.2      成員類(lèi)約束

          • 成員類(lèi)不能與外部類(lèi)重名
          • 不能在成員類(lèi)中定義static字段、方法和類(lèi)(static final形式的常量定義除外)。因?yàn)橐粋€(gè)成員類(lèi)實(shí)例必然與一個(gè)外部類(lèi)實(shí)例關(guān)聯(lián),這個(gè)static定義完全可以移到其外部類(lèi)中去
          • 成員類(lèi)不能是接口(interface)。因?yàn)槌蓡T類(lèi)必須能被某個(gè)外部類(lèi)實(shí)例實(shí)例化,而接口是不能實(shí)例化的。事實(shí)上,如示例代碼所示,如果你以成員類(lèi)的形式定義一個(gè)接口,該接口實(shí)際上是一個(gè)靜態(tài)成員類(lèi),static關(guān)鍵字對(duì)inner interface是內(nèi)含(implicit)的。

          2.3      新增語(yǔ)法

              一個(gè)成員類(lèi)實(shí)例必然所屬于其外部類(lèi)的一個(gè)實(shí)例,那么如何在成員類(lèi)內(nèi)部獲得其所屬外部類(lèi)實(shí)例呢?如示例代碼所示,采用“OuterClass.this”的形式。

          2.4      指定內(nèi)部類(lèi)實(shí)例所屬的外部類(lèi)實(shí)例

          內(nèi)部類(lèi)實(shí)例可在其外部類(lèi)的實(shí)例方法中創(chuàng)建,此新創(chuàng)建內(nèi)部類(lèi)實(shí)例所屬的外

          部類(lèi)實(shí)例自然就是創(chuàng)建它的外部類(lèi)實(shí)例方法對(duì)應(yīng)的外部類(lèi)實(shí)例。

                    另外,如示例代碼所示,對(duì)于給定的一個(gè)外部類(lèi)實(shí)例outerClass,可以直接創(chuàng)建其內(nèi)部類(lèi)實(shí)例,語(yǔ)法形式為:

          OuterClass.InnerClass innerClass = outerClass.new InnerClass();


          2.5      什么時(shí)候使用成員類(lèi)

               成員類(lèi)的顯著特性就是成員類(lèi)能訪(fǎng)問(wèn)它的外部類(lèi)實(shí)例的任意字段與方法。方便一個(gè)類(lèi)對(duì)外提供一個(gè)公共接口的實(shí)現(xiàn)是成員類(lèi)的典型應(yīng)用。

                 JDK Collection類(lèi)庫(kù)為例,每種Collection類(lèi)必須提供一個(gè)與其對(duì)應(yīng)的Iterator實(shí)現(xiàn)以便客戶(hù)端能以統(tǒng)一的方式遍歷任一Collection實(shí)例。每種Collection類(lèi)的Iterator實(shí)現(xiàn)就被定義為該Collection類(lèi)的成員類(lèi)。例如JDKAbstractList類(lèi)的代碼片斷:

           

          public abstract class AbstractList<E> extends AbstractCollection<E> implements List<E> {
              
          private class Itr implements Iterator<E> {
                   ………;
              }

               
          public Iterator<E> iterator() {
                  
          return new Itr();
               }
          }

           


              因?yàn)槎x在AbstractList中的Itr可訪(fǎng)問(wèn)AbstractList中的任意字段和方法,所以很方便實(shí)現(xiàn)Iterator,無(wú)需AbstractList對(duì)外暴露更多的接口。

              試想,如果沒(méi)有成員類(lèi)機(jī)制,只有在AbastractList源碼之外定義一個(gè)實(shí)現(xiàn)Iterator的類(lèi)Itr,該類(lèi)有一個(gè)AbstractList實(shí)例成員list,為了Itr能獲取list的內(nèi)部信息以便實(shí)現(xiàn)遍歷,AbstractList必然要向Itr開(kāi)放額外的訪(fǎng)問(wèn)接口。

          3          Local class(局部類(lèi))

          對(duì)一個(gè)靜態(tài)成員類(lèi),去掉其聲明中的“static”關(guān)鍵字,將其定義移入其外部類(lèi)

          的靜態(tài)方法或靜態(tài)初始化代碼段中就成為了局部靜態(tài)成員類(lèi)。

                 對(duì)一個(gè)成員類(lèi),將其定義移入其外部類(lèi)的實(shí)例方法或?qū)嵗跏蓟a中就成為了局部成員類(lèi)。

                 局部靜態(tài)成員類(lèi)與靜態(tài)成員類(lèi)的基本特性相同。例如,都只能訪(fǎng)問(wèn)外部類(lèi)的靜態(tài)字段或方法,但不能訪(fǎng)問(wèn)外部類(lèi)的實(shí)例字段和實(shí)例方法等。

                 局部成員類(lèi)與成員類(lèi)的基本特性相同。例如,局部成員類(lèi)實(shí)例必屬于其外部類(lèi)的一個(gè)實(shí)例,可通過(guò)OuterClass.this引用其外部類(lèi)實(shí)例等。

          另外,局部類(lèi)也有其自己的特性,如以下代碼所示:

          public class Outer {
              
          private int instanceField; 
              
          private static int staticField; 
              
              
          //define a local member class in instance code block
              {
                  
          int localVirable1 = 0;
                  
          final int localVirable2 = 1;
                  
          class Inner1 {
                      
          public Inner1() {
                          
          //can access its outer class' field and method directly
                          instanceField = 1;
                          
          //use OuterClass.this to get its corresponding outer class instance
                          Outer.this.instanceField = 1;
                          
                          
          //can not access the not final local virable in its containing code block
                          
          //System.out.print(localVirable1);
                          
                          
          //can access the final local virable in its containing code block
                          System.out.print(localVirable2);
                      }
                  }        
                  
                  
          //local class can not have privilege modifier 
                  /*public class inner2 {            
                  }
          */
              }
              
              
          // define a local static member class in static code block
              static {
                  
          class Inner2 {
                      
          public Inner2() {
                          staticField 
          = 1;
                          
          //can not access instance field and method in a local static member class 
                          
          //intanceField = 2;
                      }
                  }
              }
              
              
          public void intanceMethod() {
                  
          //define a local class in its out class' instance method
                  class Inner3 {
                  }
                  
                  
          //local class is visible only in its containning code block
                  
          //Outer.Inner2 inner2;
              }
              
              
          private static void staticMethod() {
                  
          //define a local static member class in its out class' static method
                  class Inner4 {    
                      
          public Inner4() {
                          staticField 
          = 2;
                      }
                  }
                  
                  
          //can not define a interface as a local class
                  /*interface I {
                  }
          */
              }
          }


           

          3.1      局部類(lèi)特性

          如示例代碼所示,局部類(lèi)能且只能訪(fǎng)問(wèn)其所屬代碼段中的聲明為final的局部

          變量。為什么只能訪(fǎng)問(wèn)聲明為final的局部變量呢?我們知道,局部變量在其所屬的代碼段(譬如某個(gè)函數(shù))執(zhí)行完畢后就會(huì)被回收,而一個(gè)局部類(lèi)的實(shí)例卻可以在其類(lèi)定義所屬代碼段執(zhí)行完畢后依然存在,如果它可操控非final的局部變量,用戶(hù)就可以通過(guò)該實(shí)例修改已不存在的局部變量,無(wú)意義。

          3.2      局部類(lèi)約束

          • 如示例代碼所示,內(nèi)部類(lèi)只在定義它的代碼段中可見(jiàn),不能在它所屬代碼段之外的代碼中使用;因此也就沒(méi)有public/private/default權(quán)限修飾符(無(wú)意義)
          • 不能以局部類(lèi)形式定義一個(gè)接口。局部類(lèi)只在其所屬代碼段中可見(jiàn),定義這樣的接口無(wú)意義
          • 局部類(lèi)類(lèi)名不能與其外部類(lèi)類(lèi)名重復(fù)

          3.3      什么時(shí)候使用局部類(lèi)

          局部類(lèi)大部分以匿名類(lèi)的形式使用。

                     

          4          Anonymous class(匿名類(lèi))

          沒(méi)有類(lèi)名的局部類(lèi)就是匿名類(lèi)。用一條語(yǔ)句完成匿名類(lèi)的定義與實(shí)例創(chuàng)建。例

          如如下代碼:

          public class Outer {
              
          public void instanceMethod() {
                  
          //define a nonymous class which implements Action interface and creat an instance of it
                  Action action = new Action() {
                      
          public void doAction() {
                          System.out.println(
          "a simple anonymous class demo");
                      }};
                  action.doAction();
                  
                  
          //define a nonoymous class which extends BaseClass and create an instance of it
                  new BaseClass(5) {
                      
          public void printData(){
                          System.out.println(
          "data = " + getData());
                      }
                  }.printData(); 
          //"data = 5" will be outputed
              }
          }

          interface Action {
              
          void doAction();
          }

          class BaseClass {
              
          private int data;
              
              
          public BaseClass (int data) {
                  
          this.data = data;
              }
              
              
          public int getData() {
                  
          return data;
              }
          }

           

          4.1      匿名類(lèi)特性與約束

          匿名類(lèi)是一種特殊的局部類(lèi)。局部類(lèi)的特性與約束都適用與它。

          4.2      新增語(yǔ)法

          4.2.1      繼承自某個(gè)基類(lèi)的匿名類(lèi)

          new class-name ( [ argument-list ] ) { class-body }

           

          創(chuàng)建匿名類(lèi)實(shí)例時(shí),“argument-list將被傳入其基類(lèi)(即class-name)對(duì)應(yīng)的構(gòu)造函數(shù)。

          4.2.2      實(shí)現(xiàn)某個(gè)接口的匿名類(lèi)

          new interface-name () { class-body }


          4.3      什么時(shí)候使用匿名類(lèi)

          • 該類(lèi)定義代碼段很短
          • 只需要?jiǎng)?chuàng)建該類(lèi)的一個(gè)實(shí)例
          • 類(lèi)的定義代碼與類(lèi)的使用代碼緊鄰
          • 使用匿名不影響代碼的易讀性

          譬如,如下實(shí)現(xiàn)類(lèi)似與ccallback功能的代碼就是匿名類(lèi)的典型應(yīng)用:

          File f = new File("/src");      // The directory to list

          // Now call the list() method with a single FilenameFilter argument
          // Define and instantiate an anonymous implementation of FilenameFilter
          // as part of the method invocation expression. 
          String[] filelist = f.list(new FilenameFilter() {
            
          public boolean accept(File f, String s) { return s.endsWith(".java"); }
          }); 
          // Don't forget the parenthesis and semicolon that end the method call!

           

          posted on 2007-05-23 17:46 RogerTu 閱讀(4049) 評(píng)論(8)  編輯  收藏 所屬分類(lèi): JAVA

          評(píng)論

          # re: Java內(nèi)部類(lèi)(Inner Class) 2007-05-23 18:15 BeanSoft
          好復(fù)雜啊....  回復(fù)  更多評(píng)論
            

          # re: Java內(nèi)部類(lèi)(Inner Class) 2007-06-22 13:56 summer
          終于明白了~~  回復(fù)  更多評(píng)論
            

          # re: Java內(nèi)部類(lèi)(Inner Class) 2007-06-22 13:58 summer
          “內(nèi)部類(lèi)實(shí)例可在其外部類(lèi)的實(shí)例方法中創(chuàng)建,此新創(chuàng)建內(nèi)部類(lèi)實(shí)例所屬的外

          部類(lèi)實(shí)例自然就是創(chuàng)建它的外部類(lèi)實(shí)例方法對(duì)應(yīng)的外部類(lèi)實(shí)例。”

          這句不太懂  回復(fù)  更多評(píng)論
            

          # re: Java內(nèi)部類(lèi)(Inner Class) 2007-07-08 16:34 RogerTu
          @summer
          這句話(huà)也許太羅嗦了,用示例說(shuō)明:
          public class Outer {
          public class Inner {
          }

          public Inner getInner() {
          return new Inner();
          }

          public static void main(String[] args) {
          Outer outer = new Outer();
          Inner inner = outer.getInner();
          //此時(shí)內(nèi)部成員類(lèi)實(shí)例inner對(duì)應(yīng)的外部類(lèi)實(shí)例就是outer!!!
          }

          }
            回復(fù)  更多評(píng)論
            

          # re: Java內(nèi)部類(lèi)(Inner Class) 2007-09-18 15:01 555
          寫(xiě)得不錯(cuò)  回復(fù)  更多評(píng)論
            

          # re: Java內(nèi)部類(lèi)(Inner Class) 2008-12-04 11:25 daoyongyu
          好,學(xué)習(xí)了。  回復(fù)  更多評(píng)論
            

          # re: Java內(nèi)部類(lèi)(Inner Class)[未登錄](méi) 2009-06-23 09:49 premji
          thanks  回復(fù)  更多評(píng)論
            

          # re: Java內(nèi)部類(lèi)(Inner Class) 2009-09-09 19:56 goldenfish1919
          好東西,很受用!多謝!  回復(fù)  更多評(píng)論
            


          只有注冊(cè)用戶(hù)登錄后才能發(fā)表評(píng)論。


          網(wǎng)站導(dǎo)航:
           
          主站蜘蛛池模板: 墨玉县| 永定县| 福泉市| 沅陵县| 搜索| 桂平市| 新沂市| 新竹县| 东海县| 苏尼特左旗| 沈丘县| 固安县| 乌拉特后旗| 渝北区| 宝兴县| 独山县| 五华县| 大埔县| 张家界市| 宝清县| 宜兰县| 巩留县| 绵阳市| 师宗县| 东辽县| 商都县| 类乌齐县| 南康市| 泽州县| 井研县| 阿拉善右旗| 蓝田县| 长春市| 辰溪县| 盈江县| 清徐县| 五莲县| 炎陵县| 西昌市| 博乐市| 长泰县|