java内部类详细解析
内部类的基本概念
- 当一个类的定义出现在另外一个类的类体中时,那么这个类叫做内部类 (Inner),而这个内部类所在的类叫做外部类(Outer)
- 类中的内容:成员变量、成员方法、构造方法、静态成员、构造块和静态代码块、内部类
实际作用
- 当一个类存在的价值仅仅是为某一个类单独服务时,那么就可以将这个 类定义为所服务类中的内部类,这样可以隐藏该类的实现细节并且可以 方便的访问外部类的私有成员而不再需要提供公有的get和set方法
内部类的分类
- 普通内部类 - 直接将一个类的定义放在另外一个类的类体中
- 静态内部类 - 使用static关键字修饰的内部类,隶属于类层级
- 局部内部类 - 直接将一个类的定义放在方法体的内部时
- 匿名内部类 - 就是指没有名字的内部类
普通(成员)内部类的格式
-
语法格式
访问修饰符 class 外部类的类名 { 访问修饰符 class 内部类的类名 { 内部类的类体; } }
普通内部类的使用方式
-
普通内部类和普通类一样可以定义成员变量、成员方法以及构造方法等
public class NormalOuter { private int cnt = 1; // 在类的内部定义内部类 类属于外部类的成员 隶属于对象层级 public class NormalInner{ // 普通内部类定义成员变量 定义成员方法 private int cn; public void normalInner() { System.out.println("普通内部类的构造方法执行到了"); } public void show() { System.out.println("外部类的变量cnt的数值是" + cnt); System.out.println("cn = " + cn ); } } }
-
普通内部类和普通类一样可以使用final或者abstract关键字修饰
使用final关键字修饰后 不能被继承 在开发过程中多个内部类可能用到
-
普通内部类还可以使用private或protected关键字进行修饰
public class NormalOuter{ public class NormalInner{ // 使用这两个关键字修饰后只能被类本身使用 可以声明对象使用get或set来调用 类体; } }
-
普通内部类需要使用外部类对象来创建对象
NormalOute no = new NormalOuter(); // 使用public 修饰的关键字 NormalInner.NormalOute ni = no.new NormalOute;
-
如果内部类访问外部类中与本类内部类同名的成员变量或方发时,需要使用this关键字
成员变量名; // 局部优先原则--> 形参 this.成员变量; // 内部类的成员变量 外部类名.this.成员变量; // 外部类的成员变量
静态内部类的格式
-
语法格式
访问修饰符 class 外部类的类名 { 访问修饰符 static class 内部类的类名 { 内部类的类体; } }
静态内部类的使用方式
- 静态内部类不能直接访问外部类的非静态成员 --> 因为是static关键字修饰
- 静态内部类可以直接创建对象 --> 也是因为有static关键字修饰 隶属于类层级
- 如果静态内部类访问外部类中与本类内同名的成员变量或方法时,需要 使用类名.的方式访问
局部(方法)内部类的格式
-
语法格式
访问修饰符 class 外部类的类名 { 访问修饰符 返回值类型 成员方法名(形参列表) { class 内部类的类名 { 内部类的类体; } } }
局部内部类的使用方式
- 局部内部类只能在该方法的内部可以使用–> 和局部变量差不多
- 局部内部类可以在方法体内部直接创建对象
- 局部内部类不能使用访问控制符和static关键字修饰符
- 局部内部类可以使用外部方法的局部变量,但是必须是final的。由局部内 部类和局部变量的声明周期不同所致–> JDK8开始 如果在局部内部类中修改值 会报错 final修饰的变量不能修改 虽然可以省略final关键字 有效取余不一样 使用是copy一份 如果修改会出现不一致问题 所以需要加final关键字修饰
匿名内部类的语法格式(重点)
-
语法结构
接口/父类类型 引用变量名 = new 接口/父类类型() { 方法的重写 };
-
匿名内部类的使用
当接口只使用一次时 防止内存中的方法去被占用 jdk8以后可以使用lamada表达式去实现 代码更加简单