Offer来了:Java面试核心知识点精讲(原理篇)
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

2.5 内部类

定义在类内部的类被称为内部类。内部类根据不同的定义方式,可分为静态内部类、成员内部类、局部内部类和匿名内部类这4种。

2.5.1 静态内部类

定义在类内部的静态类被称为静态内部类。静态内部类可以访问外部类的静态变量和方法;在静态内部类中可以定义静态变量、方法、构造函数等;静态内部类通过“外部类.静态内部类”的方式来调用,具体的实现代码如下:

public  class  OuterClass  {
    private  static  String  className  ="staticInnerClass";
  //定义一个静态内部类
    public  static  class  StaticInnerClass  {
      public  void  getClassName()  {
          System.out.println("className:"+className  );
      }
  }
  public  static  void  main(String[]  args)  {
      //调用静态内部类
      OuterClass.StaticInnerClass  staticInnerClass  =
                        new  OuterClass.StaticInnerClass();
      staticInnerClass.getClassName();
  }
}

上面的代码通过public static class StaticInnerClass{}代码块定义了一个静态内部类StaticInnerClass,然后定义了静态内部类的getClassName方法,在使用的过程中通过“外部类.静态内部类”的方式进行调用,具体的实现代码如下:

OuterClass.StaticInnerClass  staticInnerClass  =  new
OuterClass.StaticInnerClass()

这样就定义一个静态内部类并可以像普通类那样调用静态内部类的方法。

Java集合类HashMap在内部维护了一个静态内部类Node数组用于存放元素,但Node数组对使用者是透明的。像这种和外部类关系密切且不依赖外部类实例的类,可以使用静态内部类实现。

2.5.2 成员内部类

定义在类内部的非静态类叫作成员内部类,成员内部类不能定义静态方法和变量(final修饰的除外),因为成员内部类是非静态的,而在Java的非静态代码块中不能定义静态方法和变量。成员内部类具体的实现代码如下:

public  class  OutClass{
  private  static  int  a;
  private  int  b;
 //定义一个成员内部类
  public  class  MemberInnerClass{
      public  void  print()  {
        System.out.println(a);
        System.out.println(b);
      }
  }
}

从上述代码可以看到,在OutClass中通过public class MemberInnerClass定义了一个成员内部类,其使用方式和静态内部类相同。

2.5.3 局部内部类

定义在方法中的类叫作局部内部类。当一个类只需要在某个方法中使用某个特定的类时,可以通过局部类来优雅地实现,具体的实现代码如下:

public  class  OutClass  {
  private  static  int  a;
  private  int  b;
  public  void  partClassTest(final  int  c)  {
      final  int  d  =  1;
      //在partClassTest方法中定义一个局部内部类PastClass
      class  PastClass{
        public  void  print()  {
                  System.out.println(c);
            }
      }
  }
}

以上代码在partClassTest方法中通过class PastClass{}语句块定义了一个局部内部类。

2.5.4 匿名内部类

匿名内部类指通过继承一个父类或者实现一个接口的方式直接定义并使用的类。匿名内部类没有class关键字,这是因为匿名内部类直接使用new生成一个对象的引用。具体的实现代码如下:

public  abstract  class  Worker{
  private  String  name;
  public  String  getName()  {
      return  name;
  }
  public  void  setName(String  name)  {
      this.name  =  name;
  }
  public  abstract  int  workTime();
}
 public  class  Test  {
    public  void  test(Worker   worker){
      System.out.println(worker.getName() + "工作时间: " +
                    worker.workTime());
    }
    public  static  void  main(String[]  args)  {
      Test  test  =  new  Test();
      //在方法中定义并使用匿名内部类
      test.test(new  Worker()  {
            public  int  workTime()  {
              return  8;
          }
            public  String  getName()  {
              return  "alex";
          }
      });
    }
}

在以上代码中首先定义了一个抽象类Worker和一个抽象方法workTime,然后定义了一个Test类,在Test类中定义了一个方法,该方法接收一个Worker参数,这时匿名类需要的准备工作都已做好。在需要一个根据不同场景有不同实现的匿名内部类时,直接在test方法中新建匿名内部类并重写相关方法即可。