局部内部类和匿名内部类的概念,及简单的应用场景
11.1.5 局部内部类
- 定义在外部类方法中,作用范围和创建对象范围仅限于当前方法;
- 局部内部类访问外部类当前方法中的局部变量时,因无法保证变量的生命周期与自身相同,变量必须修饰为fianl;
- 限制类的使用范围;
public class TestLocalInnerClass {
public static void main(String[] args) {
Outer2 out = new Outer2();
In inner = out.m1();//局部内部类对外部是“不可见的”,无法从外部创建局部内部类,但是可以通过继承或者接口来接收返回的局部内部类
}
}
interface In{
void m2();
}
class Outer2{
int a = 10;
//外部类实例方法
public void m1() {
final int b = 20;//局部变量
class Inner{//局部内部类
int c = 30;
public void m2() {
System.out.println("Inner m2()");
System.out.println(Outer2.this.a);//访问外部类实例属性
System.out.println(this.c);//访问内部类的实例属性
System.out.println(b);//局部内部类访问外部类方法的局部变量,其必须是final修饰的最终变量
}
}
Inner in = new Inner();//局部内部类的使用范围
in.m2();
In i = in;
return i;
}
}
从代码里可以看到局部内部类也是可能传递出去的,那么如果局部内部类访问的外部类方法的局部变量不是final修饰的最终变量,在方法结束时方法的局部变量就会被回收,后续局部内部类的访问语句就会出错。但如果是final修饰的常量,其存储的位置与局部变量不同,其存在时效长于局部变量,才能使变量的生命周期大与局部内部类的生命周期保持一致。
11.1.6 匿名内部类
- 没有类名的局部内部类(一切特征都与局部内部类相同)。
- 必须继承一个父类或者实现一个接口;
- 定义类、实现类、创建对象的语法合并,只能创建一个该类的对象;
- 优点:减少代码量;
- 缺点:可读性较差;
public class TestLocalInnerClassForApply {
public static void main(String[] args) {
//学校一年级开设新班(班主任)
//家长提出意见(我们需要经验丰富的老师)
//Teacher teacher = new AdvancedTeacher();
//teacher.teach();
//校方没有那么多高级老师,不能让家长自主的挑选老师
//校方出台了一个内部规则(按照班级的奇偶进行均匀分派,奇数班初级,偶数班高级)
Teacher t = School.getTeacher(2);
t.teach();
}
}
class School{
public static Teacher getTeacher(int classNo) {
//初级老师
class BeginnerTeacher extends Teacher{
public void teach() {
System.out.println("初级老师");
}
}
//高级老师
// class AdvancedTeacher extends Teacher{
// public void teach() {
// System.out.println("高级老师");
// }
// }
//将两个老师类放在分派老师的方法中,变为局部内部类,限制类的使用范围,这样外界就无法看到这两个类
Teacher currentTeacher = null;//初始值
if(classNo % 2 != 0) {
currentTeacher = new BeginnerTeacher();
}else {
currentTeacher = new Teacher() {//匿名内部类
public void teach() {
System.out.println("高级老师");
}
};
}
return currentTeacher;
}
}
abstract class Teacher{
public abstract void teach();
}
匿名内部类与局部内部类的效果是差不多的,其好处就是在写代码的时候可以保持编码的流畅性,不必在为了使用类的时候离开当前代码,打断思路,但是如果要写很多的匿名内部类,不如使用局部内部类,或者使用普通类。太多的匿名内部类会使代码的可读性变差。