一个类内部包含的另一个类
例如汽车和发动机,人体和心脏的关系
分类:
- 成员内部类
- 局部内部类(包含匿名内部类)
1 成员内部类
1.2)定义
外部调用内部类需要内部类对象
编译此类
得到编译文件结构
$代表内部类的格式
1.2 内部类的使用
- 间接方式:在外部类的方法中使用内部类,main只调用外部类的方法
- 直接方式,格式:
类名 对象名 = new 类名()
外部类名.内部类名 对象名 = new 外部类名称().new内部类名称()
1.3 重名变量访问
内部类调用外部类成员变量格式:外部类.this.外部类成员变量名
this
代表本类,Outer.this
就代表外部类的本类
2 局部内部类
2.1 定义
2.2 调用
和私有变量类似,只有本类能用
注意: 局部内部类不能写权限修饰符
2.3 局部内部类的final
如果要访问所在方法的局部变量,那么这个局部变量必须是 有效final(不能改变)
java8开始,只要它事实不变,final关键字就可省略
原因:
- new出来的对象在堆内存中
- 局部变量和方法同在栈内存中
- 方法运行结束后立即出栈,局部变量就会随之消失
- new出来的对象会在堆内存持续存在,直到垃圾回收
这样就会造成new出来的对象无法再次使用已经消失了的局部变量,但是此时new出来的对象会复制得到局部变量的值,所以此值不能改变
3 匿名内部类
3.1 定义格式
接口名 对象名 = new 接口方法() {
// 覆盖重写所有抽象方法
};
大括号内就是一个内部类的内容,只是这个内部类没有名字
impl2.method();
实现类覆盖重写了抽象方法
实现类覆盖重写了抽象方法
匿名内部类实现了方法
3.2 内部匿名类的使用
何时使用
如果接口的实现类(或者是父类的子类)只需要使用唯一的一次,
那么这种情况下就可以省略掉该类的定义,而改为使用【匿名内部类】。
格式解析:
- new创建对象
- 接口名就是需要实现接口
- {} 内就是匿名内类ed内容
注意:
- 匿名内部类在创建对象的时候只能使用唯一的一次,想多次使用需要继续创建匿名内部类或者老老实实创建接口的实现类
- 匿名对象在调用方法的时候只能调用唯一一次,如果同一个对象想调用多个方法那就必须有名字
- 匿名内部类是省略了实现类/子类,匿名对象是省略了对象名