`
guanjh
  • 浏览: 229168 次
  • 性别: Icon_minigender_1
  • 来自: 成都
社区版块
存档分类
最新评论

Java内部类(Inner Class)详解[转]

    博客分类:
  • Java
阅读更多
简单的说,内部(inner)类指那些类定义代码被置于其它类定义中的类;而对于一般的、类定义代码不嵌套在其它类定义中的类,称为顶层(top-level)类。对于一个内部类,包含其定义代码的类称为它的外部(outer)类。
1          Static member class(静态成员类)
类声明中包含“static”关键字的内部类。如以下示例代码,
Inner1/Inner2/Inner3/Inner4就是Outer的四个静态成员类。静态成员类的使用方式与一般顶层类的使用方式基本相同。
java 代码
 
  1. public class  Outer{  
  2.     //just like static method, static member class has public/private/default access privilege levels  
  3.       
  4.     //access privilege level: public   
  5.     public static class Inner1 {  
  6.         public Inner1() {  
  7.             //Static member inner class can access static method of outer class  
  8.             staticMethod();      
  9.             //Compile error: static member inner class can not access instance method of outer class  
  10.             //instanceMethod();    
  11.         }  
  12.     }  
  13.       
  14.     //access privilege level: default   
  15.     static class Inner2   
  16.       
  17.     //access privilege level: private   
  18.     private static class Inner3 {  
  19.         //define a nested inner class in another inner class   
  20.         public static class Inner4   
  21.     }  
  22.   
  23.     private static void staticMethod() {  
  24.         //cannot define an inner class in a method  
  25.         /*public static class Inner4() */  
  26.     }  
  27.       
  28.     private void instanceMethod() {  
  29.         //private static member class can be accessed only in its outer class definition scope  
  30.         Inner3 inner3 = new Inner3();  
  31.         //how to use nested inner class  
  32.         Inner3.Inner4 inner4 = new Inner3.Inner4();  
  33.     }  
  34. }  
  35.   
  36. class Test {  
  37.     Outer.Inner1 inner1 = new Outer.Inner1();  
  38.     //Test and Outer are in the same package, so Inner2 can be accessed here  
  39.     Outer.Inner2 inner2 = new Outer.Inner2();   
  40.     //Compile error: Inner3 cannot be accessed here  
  41.     //Outer.Inner3 inner3 = new Outer.Inner3();   
  42. }  

1.1      静态成员类特性

静态成员类可访问外部类的任一静态字段或静态方法

像静态方法或静态字段一样,静态成员类有public/private/default权限修饰符

1.2      静态成员类约束

静态成员类不能与外部类重名

像外部类的静态方法一样,不能直接访问外部类的实例字段和实例方法

静态成员类只能定义于外部类的顶层代码或外部类其它静态成员类的顶层代码中(嵌套定义);不能定义于外部类的某个函数中。

1.3      新增语法
    如示例代码所示,可以以“OuterClass.InnerClass”的方式来引用某个内部类。
1.4      什么时候使用静态成员类
B为A的辅助类,且只为A所用时,可将B定义为A的静态成员类。例如JDK中的LinkedList类就有Entry静态成员类:
java 代码
 
  1. public class LinkedList<e></e><E><e> </e>extends AbstractSequentialList<e></e><E><e>
    </e>
  2.    …;  
  3.    private static class Entry<e></e><E><e> {  </e>
  4.     E element;  
  5.     Entry<E><e> next;  </e>
  6.     Entry<E><e> previous;  </e>
  7.   
  8.     Entry(E element, Entry<E><e> next, Entry<e></e></e><E><e><e> previous) {  </e></e>
  9.         this.element = element;  
  10.         this.next = next;  
  11.         this.previous = previous;  
  12.     }  
  13.     }  
  14.     …;  
  15. }  

   显然,Entry用来表示LinkedList中的一个结点,只被LinkedList自身使用。

2          Member class(成员类)
一个静态成员类,若去掉“static”关键字,就成为成员类。如下示例代码,Inner1/Inner2/Inner3/Inner4就是Outer的四个成员类
 

java 代码
 
  1. public class Outer {  
  2.     //just like instance method, member class has public/private/default access privilege levels  
  3.     private int data;  
  4.       
  5.     //access privilege level: public   
  6.     public class Inner1 {  
  7.         private int data;  
  8.         private int data1;  
  9.         public Inner1() {  
  10.             //member class can access its outer class' instance field directly  
  11.             data1 = 1;  
  12.             //itself data field  
  13.             data = 1;  
  14.             //its outer class instance field  
  15.             Outer.this.data = 1;  
  16.         }  
  17.     }  
  18.       
  19.     //access privilege level: default  
  20.     class Inner2 {  
  21.         //can not define static filed, method, class in member class  
  22.         //static int j = 1;  
  23.           
  24.         //but, "static final" compound is allowed   
  25.         static final int CONSTANT = 1;  
  26.     }  
  27.       
  28.     //access privilege level: private   
  29.     private class Inner3 {  
  30.         public class Inner4   
  31.     }  
  32.       
  33.     //in fact, Inner5 is not a member class but a static member class  
  34.     interface Inner5   
  35.       
  36.     private static void staticMethod() {  
  37.         //can not create a member class instance directly in outer class' static method  
  38.         //Inner1 inner1 = new Inner1();  
  39.     }  
  40.       
  41.     private void instanceMethod() {  
  42.         //can create a member class instance in outer class' instance method  
  43.         Inner1 inner1 = new Inner1();  
  44.     }  
  45. }  
  46.   
  47. class Test {  
  48.     public Test() {  
  49.         //cannot create member class instance directly in class other than outer class  
  50.         //Outer.Inner2 inner2 = new Outer.Inner2();  
  51.           
  52.         //create a member class instance outside it's outer class  
  53.         Outer outer = new Outer();  
  54.         Outer.Inner1 inner1 = outer.new Inner1();  
  55.     }  
  56. }  
 
2.1      成员类特性
·        类似于外部类的实例函数,成员类有public/private/default权限修饰符
·        一个成员类实例必然所属一个外部类实例,成员类可访问外部类的任一个实例字段和实例函数。
2.2      成员类约束

成员类不能与外部类重名

不能在成员类中定义static字段、方法和类(static final形式的常量定义除外)。因为一个成员类实例必然与一个外部类实例关联,这个static定义完全可以移到其外部类中去

成员类不能是接口(interface)。因为成员类必须能被某个外部类实例实例化,而接口是不能实例化的。事实上,如示例代码所示,如果你以成员 类的形式定义一个接口,该接口实际上是一个静态成员类,static关键字对inner interface是内含(implicit)的。

2.3      新增语法
    一个成员类实例必然所属于其外部类的一个实例,那么如何在成员类内部获得其所属外部类实例呢?如示例代码所示,采用“OuterClass.this”的形式。
2.4      指定内部类实例所属的外部类实例
内部类实例可在其外部类的实例方法中创建,此新创建内部类实例所属的外
部类实例自然就是创建它的外部类实例方法对应的外部类实例。
          另外,如示例代码所示,对于给定的一个外部类实例outerClass,可以直接创建其内部类实例,语法形式为:
OuterClass.InnerClass innerClass = outerClass.new InnerClass();

2.5      什么时候使用成员类
     成员类的显著特性就是成员类能访问它的外部类实例的任意字段与方法。方便一个类对外提供一个公共接口的实现是成员类的典型应用。
       以JDK Collection类库为例,每种Collection类必须提供一个与其对应的Iterator实现以便客户端能以统一的方式遍历任一 Collection实例。每种Collection类的Iterator实现就被定义为该Collection类的成员类。例如JDK中 AbstractList类的代码片断:
java 代码
 
  1. public abstract class AbstractList<E><e> </e>extends AbstractCollection<E><e> </e>implements List<e></e><E><e>{  </e>
  2.     private class Itr implements Iterator<e></e><E><e> {  </e>
  3.          ………;  
  4.     }  
  5.   
  6.      public Iterator<E><e> iterator() {  </e>
  7.         return new Itr();  
  8.      }  
  9. }  
 
    因为定义在AbstractList中的Itr可访问AbstractList中的任意字段和方法,所以很方便实现Iterator,无需AbstractList对外暴露更多的接口。
    试想,如果没有成员类机制,只有在AbastractList源码之外定义一个实现Iterator的类Itr,该类有一个AbstractList实例 成员list,为了Itr能获取list的内部信息以便实现遍历,AbstractList必然要向Itr开放额外的访问接口。
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics