首页 > 代码库 > java内部类

java内部类

 在一个类内部定义的类叫做内部类,内部类的宿主即外部类。java内部类包括成员内部类,局部内部类,匿名内部类。

1.成员内部类

    访问权限修饰符:外部类的上一级程序单元是包,所以外部类只有public和默认权限两种访问权限修饰符,而内部类的上一级程序单元是外部类,所以内部类和普通的成     员一样有四种访问权限修饰,即public,protected,默认,private。

    class文件名:当一个包含内部类的类文件被编译后,相应的目录下会出现两个class文件,一个是Outer.class,另一个是Outer$Inner.class,其中Outer为外部类的类           名,Inner为内部类的类名。

    变量同名问题:有时会出现这样一种情况,外部类的成员变量,内部类的成员变量,内部类的局部变量有相同的名字,这时可用外部类.this.变量名,this.变量名,变量名     对三个变量区分。

     访问问题:外部类对内部总是透明的,而内部类对外部类是不透明的,这就是说内部类可以直接通过成员名访问到外部成员(当然这也是有条件限制的,下面会有提           到),而外部类不能直接通过成员名访问内部成员。总之,内部类调用外部成员的方式是特别的,而外部类调用内部类的成员使用的方式是传统方式。

1.1静态内部类

      静态内部类由static修饰的成员内部类。

      在其他类中访问另一个类的内部类:格式为Outer.Inner name=new Outer.Inner(),显然这种类名可以很好的表达层级逻辑,避免了把一个类的类名取得过长。                 如果把Outer.Inner看作一个整体的话,静态内部类和普通的类声明方式是一样的,而且事实上也基本相同,区别之一是静态内部类的访问权限有四种,而外部类只有两                 种,之二是静态内部类访问外部类时和一个外部类访问另一个外部类稍有不同,下面会讲到,除此之外,静态内部类的用法和普通的外部类基本无二,和c++中的嵌套                 类(c++中没有和java中的非静态内部类对应的概念)是一样的。

                      静态内部类和外部类的相互访问问题:

     当静态内部类的方法访问外部类的成员时,不能访问外部类的非静态成员,原因是如上所述,我们可以在其他类中访问另一个类的内部类,此时,由于我们可以不                 实例化外部类而直接实例化它的内部类,所以不能在内部类的方法(或初始化块)中调用外部类的非静态成员;但是静态内部类的直接访问外部类的静态成员时则不存                 在这个问题,我们可以通过静态成员变量名(或方法名)直接访问静态成员,而不用使用“类名.成员名”这样的传统方式调用类成员,这也是上文所说的静态内部类和普                 通类的第二个不同。

      当外部类访问内部类成员时,由于内部类对外部类是不透明的,所以必须通过创建内部类的实例,再通过实例调用其成员,若调用静态内部类的类成员,则必须通                 过“Inner.成员名”这样的传统格式。

                      接口问题:接口内也可以定义内部类,但必须为静态内部类,即只能用public static修饰,既然只有这一种情况,故public static可以省略,这和接口内方法的public                修饰符,属性的public final修饰符可以省略是一个道理。此外接口内也可以定义接口,但通常不这样做。

1.2非静态内部类

      非静态内部类是java语言的一大特点,与静态内部类有本质的不同,它自身包含一个对外部类的实例的引用,可以访问外部类的任意成员,这就是说,若存在非静                  态内部类的实例,则它的外部类也一定存在实例。注意,非静态内部类没有静态成员,包括静态属性,静态方法,静态初始化块。

      在其他类中访问另一个类的内部类:格式为Outer.Inner name=outer.new Inner(),其中小写的outer表示外部类的实例,这表明实例化非静态内部类之前必须先实                    例化外部类。

                      内部类和外部类的互相访问:非静态内部类访问外部类成员(包括静态和非静态成员)时没有任何限制,可以直接使用外部成员的名称访问,但外部类访问内部类                 成员时,根据静态成员不能访问非静态成员的原则,外部类的静态成员不能访问非静态内部类的任何成员,即使是实例化非静态内部类也是非法的,而非静态内部类调                 用外部类成员时则没有这个限制,原因很简单,非静态内部类是没有静态成员的。外部类的非静态成员访问非静态内部类成员时使用“内部类实例.成员名”的方式访问。


2.局部内部类

    在方法内定义的类为成员内部类,由于成员内部类只能在方法内部被访问,故局部内部类及其成员都不需要访问控制符和static修饰。在类文件的命名方面,由于同一个       类的不同方法内部可能定义相同名字的局部内部类,故局部内部类的class文件格式为“Outer$NInner.class,其中N代表数字,含义是局部内部类所在方法的次序。


3.匿名内部类

   匿名内部类适合那些只需要使用一次的类,经常和接口结合取代函数指针,比如用java编写桌面程序时事件监听器的实现。 匿名内部类必须且仅仅继承一个父类或实现一     个接口。匿名内部类不能是抽象类且没有构造器,但可以有初始化块。局部内部类可以访问外部类的成员变量,但同样要遵循静态成员不能访问非静态成员的原则,如果内部     类需要访问所在方法的局部变量,则该变量必须由final修饰。                  




java内部类