Java的内部类一共有四种,分别是静态内部类成员内部类局部内部类匿名内部类。有时候,我们很难记住四种内部类,不妨这样想,四种内部类对应了Java类的四种组成,Java有静态方法和静态变量,那静态内部类就是和这个对应着,而类有成员函数和成员变量那一定也就有成员内部类;Java有局部变量也就对应了局部内部类;最后,匿名内部类对应了我们new一个对象,这样想,四种内部类就比较好掌握了。废话少说,逐一介绍。

静态内部类:

静态内部类有两个特点:

1.       静态内部类使用static修饰,声明在类体中

2.       静态内部类可以访问外部累的静态成员(就好像静态方法可以访问静态变量一样)

看代码:

 
  
  1. public class StatClas { 
  2.     public static int w=9
  3.     static class Test{ 
  4.         private int i=9
  5.         public static int j=8
  6.         public int get(){ 
  7.             System.out.println("内部类的J是"+j); 
  8.             return i; 
  9.         } 
  10.         public static int get0(){ 
  11.             System.out.println("外部类W的值是"+w); 
  12.             return j; 
  13.         } 
  14.     } 
  15.     public static void main(String args[]){ 
  16.         /***可以通过调用静态方法的办法调用静态内部类,然后调用其静态方法**/ 
  17.         StatClas.Test.get0(); 
  18.         /*** 
  19.          * 静态内部类: 
  20.          * StatClas相当于Test类的包,为Test声明一个命名空间 
  21.          * 静态内部类的作用域,类似于静态变量,类加载以后就存在 
  22.          * 可以在静态内部类中访问静态成员和静态方法。 
  23.          * 静态内部类的好处是:将内部类封装入外部类,为内部类声明一个命名空间 
  24.          *  
  25.          * */ 
  26.         //直接在本包中声明内部类的对象 
  27.         Test t= new Test(); 
  28.         //通过对象调用内部类的成员方法 
  29.         t.get(); 
  30.         //通过外部类名.内部类 声明对象 
  31.         StatClas.Test t0= new StatClas.Test(); 
  32.         t0.get(); 
  33.     } 
  34.      

成员内部类

成员内部类有两个特点:

1.  声明在类体中,不使用static,具有类的成员特征,也就是,必须使用外部类的实例才能创建内部类实例

2.  内部类实例可以访问外部类的成员变量

看代码:

 
  
  1. public class InClass { 
  2.     private int i=9
  3.     public String name= "inclass"
  4.     public static String name0="test"
  5.     public class Test{ 
  6.         private String name="test"
  7.         public int j=9
  8.         public void get(){ 
  9.             System.out.println("name的值"+name+" "+"i的值"+i+" "+"name0的值"+name0); 
  10.         } 
  11.     } 
  12.     public static void main(String args[]){ 
  13.         //不可以像静态内部类的声明一样声明Test对象 
  14.         //Test t= new Test(); 
  15.         //声明内部类对象的方式,也不可以,因为内部类是成员内部类,需要有外部类的实例 
  16.         //Test t= new InClass.Test(); 
  17.          
  18.         /**** 
  19.          * 成员内部类是外部类的成员,是依据于外部类对象而存在的,所以声明内部类对象的时候要通过外部累对象来声明 
  20.          * ***/ 
  21.         InClass ic= new InClass(); 
  22.         Test t= ic.new Test(); 
  23.         t.get(); 
  24.         System.out.println(t.getClass()); 
  25.         /**输出为 
  26.          * name的值test i的值9 name0的值test 
  27.          * class com.innnerclass.zhuxuli.InClass$Test 
  28.          *  
  29.          * */ 
  30.     } 

局部内部类

把类声明在方法中,就是局部内部类,作用域类似局部变量

看代码

 
  
  1. public class LoClass { 
  2.     private final int i=9
  3.     private int d=3
  4.     private final String name="loclass"
  5.     public void testClass(){ 
  6.         int j=10
  7.         //int d=5; 
  8.         final int w=2
  9.         final String name="testclass"
  10.         class Test{ 
  11.             /*** 
  12.              * 局部内部类访问的方法中的局部变量必须为final类型 
  13.              * 然而,局部变量可以访问成员变量,成员变量无须final定义 
  14.              * 成员变量中的声明的变量被方法中重新声明为局部变量,如果需要在局部内部类中访问,必须定义为final类型 
  15.              * ***/ 
  16.             public int get(){ 
  17.                 return w+name.length(); 
  18.             } 
  19.             public int get0(){ 
  20.                 return i+w; 
  21.             } 
  22.             public int get1(){ 
  23.                 return d+w; 
  24.             } 
  25.         } 
  26.         Test t= new Test(); 
  27.         System.out.println("get方法"+t.get()+"\r\n get0方法"+t.get0()+"\r\n get1方法"+t.get1()); 
  28.     } 
  29.     public static void main(String args[]){ 
  30.         LoClass lc= new LoClass(); 
  31.         lc.testClass(); 
  32.         /** 
  33.          * 输出结果是: 
  34.          * get方法11 
  35.          * get0方法11 
  36.          * get1方法5 
  37.          * ***/ 
  38.     } 
  39.      

匿名内部类

在长篇幅的说明匿名内部类这个非常重要的概念前,我们先用简单的话说明什么是匿名内部类。

举例子

 
  
  1. public  class NimClass { 
  2.     private int w=9
  3.     private final int z=10
  4.     private static int x=4
  5.     public static void main(String args[]){ 
  6.         int i=5
  7.         final int j=8
  8.         final String name="测试匿名内部类"
  9.         Test t= new Test(){ 
  10.             int get(){ 
  11.                 System.out.println("匿名内部类实现了Test"); 
  12.                 /** 
  13.                  * 1、虽然局部内部类的所有规则适用于匿名内部类 
  14.                  * 但是匿名内部类不能访问外部类的成员变量和成员函数,但是可以访问方法中的final变量 
  15.                  * 2、匿名内部类是实现的某一个抽象类或者接口,所以他不能定义任何静态方法,成员方法 
  16.                  * 匿名内部类不能是public,protected,private,static 
  17.                  * 3、匿名内部类只能访问外部累的静态变量和静态方法 
  18.                  *  
  19.                  * ***/ 
  20.                 System.out.println(j+x); 
  21.                 return 1
  22.             } 
  23.         }; 
  24.         Test0 t0= new Test0(){ 
  25.             public int get(){ 
  26.                 System.out.println(); 
  27.                 return 2
  28.             } 
  29.         }; 
  30.     } 
  31. abstract class Test{ 
  32.     abstract int get(); 
  33. interface Test0{ 
  34.     int get(); 

匿名类是不能有名称的类,所以没有办法引用他们。必须在创建时,作为new语句的一部分类声明匿名类,这就要采用另一种形式的new语句,如下所示: new <类或接口> <类的主体> 这种形式的new语句声明一个新的匿名类,它对一个给定的类进行扩展,或者实现一个给定的接口。它还创建那个类的一个新实例,并把它作为语句的结果而返回。要扩展的类和要实现的接口是new语句的操作数,后跟匿名类的主体。如果匿名类对另一个类进行扩展,它的主体可以访问类的成员、覆盖它的方法等等,这和其他任何标准的类都是一样的。如果匿名类实现了一个接口,它的主体必须实现接口的方法。

 注意匿名类的声明是在编译时进行的,实例化在运行时进行。这意味着for循环中的一个new语句会创建相同匿名类的几个实例,而不是创建几个不同匿名类的一个实例。

在使用匿名内部类时,要记住以下几个原则:

1、匿名内部类不能有构造方法。

2、匿名内部类不能定义任何静态成员、方法和类。  

3、匿名内部类不能是public,protected,private,static  

4、只能创建匿名内部类的一个实例。

5、一个匿名内部类一定是在new的后面,用其隐含实现一个接口或实现一个类。  

6、因匿名内部类为局部内部类,所以局部内部类的所有限制都对其生效。内部类只能访问外部类的静态变量或静态方法。

匿名类和内部类中的中的 this :有时候,我们会用到一些内部类和匿名类。当在匿名类中用 this时,这个 this则指的是匿名类或内部类本身。这时如果我们要使用外部类的方法和变量的话,则应该加上外部类的类名。