1.内部类:
类里面的类,就称之为内部类。
内部类的class文件的形式:Outer$Inner.class
内部类对象实例化:Outer.Inner in = new Outer().new Inner();
1)内部类用法:
内用外,随意使用;外用内,需要内部类对象。
这里可以和局部变量与全局变量一起理解。
2)分类:
I.成员内部类
●间接使用成员内部类:在外部类的方法中,使用内部类;main只是调用内部类的方法。
●直接使用成员内部类:【Outer.Inner in = new Outer().new Inner();】
●变量重名时:Outer.this.外部类成员变量名
下面的代码就两种都写上了,注释里都解释了
class Outer{ //外部类
String msg = "外部类的全局变量";
class Inner{ //内部类
String msg ="内部类的全局变量";
public void print(){
String msg ="内部类的局部变量";
System.out.println(msg); //局部变量,就近原则
System.out.println(this.msg); //内部类的全局变量
System.out.println(Outer.this.msg); //直接访问外部类的私有属性
}
}
public void fun(){ //外部类方法
System.out.println(new Inner().msg); //间接利用内部类(匿名)对象访问内部类中的私有属性
}
}
public class Test{
public static void main(String args[]){
Outer.Inner in = new Outer().new Inner(); //实例化内部类对象
in.print(); //调用内部类的方法
Outer out = new Outer(); //实例化外部类对象
out.fun(); //调用外部类的方法
}
}
/运行结果:
内部类的局部变量
内部类全局变量
外部类全局变量
内部类全局变量
II.局部内部类
在方法中定义的内部类。
注意:"局部"只有当前所属方法才能使用,出了这个方法外面就不能用了。(即局部内部类的对象,必须定义在方法里面)
class Outer{
public void methodOuter(){
class Inner{ //局部内部类
final int num = 10; //所在方法的局部变量
public void methodInner(){
System.out.println(num);
}
}
new Inner().methodInner(); //内部类实例化对象调用methodInner()输出
}
}
public class Test2 {
public static void main(String[] args) {
Outer outer = new Outer();
outer.methodOuter();
}
}
局部内部类的final问题:
局部内部类,如果希望访问所在方法的局部变量,那么这个局部变量必须是【有效final的】。
备注:从Java 8+开始,只要局部变量事实不变,那么final关键字就可以省略。
原因:
●new出来的对象在堆内存当中,局部变量是跟着方法走的,在栈内存当中。
●方法运行结束之后,立刻出栈,局部变量就会立刻消失。但是new出来的对象会在堆内存中持续存在,直到垃圾回收。
III.匿名内部类
①何时使用匿名内部类?
如果接口的实现类(或者是父类的子类)只需要使用唯一的一次,那么这种情况下就可以省略掉该类的定义,而改为使用【匿名内部类】。
随用随定义!
//IMyInterface即创建的接口,里面有抽象方法method。
//使用匿名内部类
IMyInterface obj = new IMyInterface() {
@Override
public void method() {
System.out.println("匿名内部类实现了方法!");
}
};
obj.method();
②对匿名内部类格式进行分析:
IMyInterface obj = new IMyInterface() {
@Override
//覆盖重写所有抽象方法
};
●new代表创建对象的动作,接口名称(IMyInterface)就是匿名内部类需要实现哪个接口。
●{ … };这才是匿名内部类的内容。
③需要注意的问题:
●匿名内部类:在【创建对象】的时候,只能使用唯一一次。
如果希望多次创建对象,就必须使用单独定义的impl实现类。
●匿名对象:在【调用方法】的时候,只能调用唯一一次。
如果希望同一个对象调用多次方法,就必须给对象起名。
●匿名内部类是省略了【实现类/子类名称】,但是匿名对象是省略了【对象名称】。
二者不是同一个意思。