内部类的概念:
把类B定义在类A中,类B就被称为内部类。
内部类的分类:
A.成员内部类(定义在类的成员中,方法外)
B.局部内部类(定义在类的方法中)
内部类定义在类中的局部位置上时,只能访问该局部被final修饰的局部变量。成员内部类没有权限访问局部变量。
为什么局部内部类只能访问被final修饰的局部变量?
是变量的作用域的问题,因为虽然匿名内部类在方法的内部,但实际编译的时候,内部类编译成Outer.Inner,这说明内部类所处的位置和外部类中的方法处在同一个等级上,内部类里面使用外部类的局部变量时,其实就是内部类的对象在使用它,内部类对象生命周期中都可能调用它,而内部类试图访问外部方法中的局部变量时,外部方法的局部变量很可能已经不存在了,那么就得延续其生命,拷贝到内部类中,而拷贝会带来不一致性,从而需要使用final声明保证一致性,而使用final修饰符不仅会保持对象的引用不会改变,而且编译器还会持续维护这个对象在回调方法中的生命周期.所以这才是final变量和final参数的根本意义.,所以方法中的变量或参数只有为final,内部类才可以引用,当访问成员变量时即使不是final也没任何问题。
内部类常见的标识符:
A.private 为了数据的安全性。
B.static 方便调用
实际开发中最常用的:匿名内部类:
new 类名或者接口名() { //这个类名一般是抽象类名当然也可不是
重写类中接口的方法。
或者自己定义方法。(一般肯定不会自己定义方法)
};
理解:本质是继承了类或者实现了接口的子类匿名对象。
abstract class Fu{
public abstract void show();
}
class Outer{
public void method(){
//本质是继承了类或者实现了接口的子类匿名对象
new Fu(){
public void show(){
System. out.println("show" );
}
}.show(); //这一个整体是一个对象,通过这个对象来调用方法
}
}
调用:
Outer o = new Outer();
o.method();
但这样也有一个弊端。比如当抽象类中有很多抽象方法都要要所有的都要写一遍。注意 new Fu(){….}的本质是继承了类或者实现了接口的子类匿名对象。
也可以 Fu f = new Fu(){….} 然后 f.show();
abstract class Fu{
public abstract void show();
}
class Outer{
public void method(){
//本质是继承了类或者实现了接口的子类匿名对象
Fu f = new Fu(){
public void show(){
System. out.println("show" );
}
}; //不要忘了这里的 ; 号
f.show();
}
}
匿名内部类的最最常用的方法:作为一个参数来传递而不需要生成类的实例。
//定义接口一个抽象方法show();
interface Inter{
public abstract void show();
}
//实现接口
class InterImp implements Inter{
public void show(){
System.out.println("Dream!");
}
}
//该类的一个参数为Inter i
class InterDemo{
public void method(Inter i){
i.show();
}
}
//主类省略
InterImp ii = new InterImp();
InterDemo id = new InterDemo();
id.method(new InterImp());
id.method(ii);
//这两种方法都没问题
还有一种方法不需要实现继承即可
id.method(new Inter(){
public void show(){
System. out.println("Dream" );
}
});