定义在类中的类叫做内部类。在Java中有四种类型的内部类,分别是非静态内部类、静态内部类、局部内部类、匿名内部类,下面依次介绍这四种内部类
非静态内部类
- +类的成员之一
- +可以被private、protected、public修饰
- +不用static修饰
- +非静态内部类可以直接访问外部类的属性和方法,但外部类只能通过非静态内部类的实例访问非静态内部类的内容(非静态内部类有一个对外部类的实例的引用,[OutterClassName].this)
- +非静态内部类中不能拥有静态属性,静态方法,静态代码块
- +如果存在一个非静态内部类的对象,则一定存在一个被它寄生的外部类对象。但外部类存在时,非静态内部类对象不一定存在
- +类文件的名字:OutterClass$InnerClass.class
- +创建非静态内部类
- +在外部类的非静态方法中:InnerClass instance = new InnerClass();
- +在外部类的静态方法或者外部类外(权限允许的时候):OutterClass.InnerClass instance = new OutterClass().new InnerClass();(注:因为内部类实例必须依赖于外部类实例存在,所以必须先创建外部类的实例)
静态内部类
- +类的成员之一
- +被static修饰的内部类
- +可以被private、protected、public修饰
- +静态内部类中可以有非静态成员和静态成员
- +类文件的名字:OutterClass$InnerClass.class
- +创建静态内部类:
- +在外部类中:InnerClass instance = new InnerClass();
- +在外部类外(权限允许时):OutterClass.InnerClass instance = new OutterClass.InnerClass();
局部内部类
- +在外部类的方法中定义
- +只在所定义的方法中有效
- +与局部变量一样,不能被private、protected、public、static关键字修饰
- +类文件的名字:OutterClass.[n]InnerClass.class(其中n为阿拉伯数字。在同一个外部类中,静态内部类,非静态内部类不能重名,所以不用数字区分类文件名,但是不同的方法中可能会有同名的局部内部类,所以需要数字来进行区别)
- +被局部内部类使用的方法的局部变量为final类型(在JDK1.8之前,该成员变量必须用final关键字修饰,在JDK1.8中默认添加final,可以不用显式用final修饰,但是该变量的使用行为与被final修饰时一致)
匿名内部类
- +适合创建只使用一次的类(创建匿名类的同时,自动创建匿名内部类的对象)
- +匿名内部类不能重复使用
- +格式:
new 实现接口() | 父类构造器(实参列表){
// 匿名内部类的类体部分
}
- +匿名内部类只能实现一个接口或者继承一个类(不一定是抽象类)
- +匿名内部类不能显式创建构造器:实现接口时,默认有一个无参构造器;继承父类来创建匿名内部类时,匿名内部类拥有和父类相似的构造器,此处的相似指的是拥有相同的形参列表
- +实现接口时必须实现接口的所有方法;如果继承抽象父类时则必须实现抽象父类中所有的抽象方法
- +与局部内部类一样,被匿名内部类使用的方法的局部变量为final类型