类的权限修饰符:
1.外部类:public/(default)
2.成员内部类:public/protected/(default)/private
3.局部内部类:什么都不能写
成员内部类(定义在一个类中)
格式:
修饰符 class 外部类名称 {
修饰符 class 内部类名称 {
}
}
注意事项:
1.内用外,可以随意访问;外用内,需要创建内部对象
2.编译后,会生成外部类名.class与外部类名$内部类名.class,因此,给类命名时要尽量避免使用'$'
使用方法:
1.间接方式:在外部类的方法中,使用内部类,在main方法中调用外部类的方法
2.直接方法:创建对象使用
外部类名称.内部类名称 对象名 = new 外部类名称().new 内部类名称
内部类中,重名变量的访问:
1.在内部类方法中,访问局部变量,直接调用
2.在内部类方法中,访问内部类成员变量,this.变量名
3.在内部类方法中,访问外部类成员方法,外部类名.this.变量名
局部内部类(定义在一个方法内部)
格式:
修饰符 class 外部类名称 {
修饰符 返回值类型 外部类方法名(参数列表){
class 局部内部类名称{
}
}
}
注意事项:
1.局部内部类,如果希望访问所在方法的局部变量,那么这个局部变量必须是有效final的
2.从Java 8+开始,只要局部变量事实不变,那么final关键字可以省略
原因:
1.new出来的对象在堆内存中
2.局部变量跟着方法走,在栈内存中
3.方法运行结束后,立即出栈,局部变量就会跟着消失
4.但是new出来的对象会在堆内存当中持续存在,知道垃圾回收消失,所以要想访问方法中的局部变量,就得保证这个变量有效final,这样对象使用的时候会赋值这个变量的值
匿名内部类
如果接口的实现类(或父类的子类)只需要使用唯一的一次,就可以省略该类的定义,改为使用匿名内部类
格式:
接口名称 对象名 = new 接口名称(){
//覆盖重写所有抽象方法
}
注意事项:
1.new代表创建对象的动作
2.接口名称就是匿名内部类需要实现的接口
3.{}里为匿名内部类的内容
4.匿名内部类,在【创建对象】的时候,只能使用唯一的一次
5.匿名内部类省略了实现类名称/子类名称,而匿名对象是省略了对象名。匿名类与匿名对象不是一回事