一、内部类:定义在类中的类,就叫内部类
特点就是内部类可以访问外部类的成员,包括私有成员。
内部类分为成员内部类和局部内部类:
1.成员内部类:在外部类的成员位置定义的类
2.成员内部类的访问格式:
1)访问格式:(非静态)
在测试类中访问内部类的格式:
外部类名.内部类名 对象名 = new 外部类名().new内部类名();
如: Outer.Inner oi = new Outer().new.Inner();
2)访问格式:(静态)
在测试类中访问内部类的格式:
外部类名.内部类名 对象名 = new 外部类名.内部类名() ;
如: Outer.Inner oi = new Outer.new.Inner();
特点:被静态修饰的成员内部类,它里面的成员方法(可以静态/非静态)只能访问外部类中静态的成员!(必须使用static修饰)
class Outer{
public int num = 100;
public static int num2 = 50 ;
//加入static修饰的成员内部类
static class Inner{
//定义一个成员方法
public void show() {
//System.out.println(num); //外部类的成员变量没有加入static修饰,不能访问
System.out.println(num2);
}
public static void show2() {
//System.out.println(num); //外部类的成员变量没有加入static修饰,不能访问
System.out.println(num2);
}
}
}
//测试类中
public class Demo{
public static void main(String[] args) {
//静态的成员内部类中成员的访问方式:
//外部类名.内部类名 对象名 = new 外部类名.内部类名() ;
Outer.Inner oi = new Outer.Inner4() ;
oi.show();
oi.show2();
System.out.println("-------------------");
//对于show2()是内部类中的静态的成员方法
Outer.Inner.show2();
}
}
3.局部内部类:在外部类的局部位置(外部类的成员方法中定义的类)
1) 特点:
a.可以访问外部类的所有成员,包括私有
b.在外部类中成员方法中访问内部类成员,通过创建局部内部类对象来访问
2) 注意点:
JDK7以前(包含JDK7),局部内部类访问局部变量,局部变量必须加入final修饰,否则报错!
JDK7以后,局部变量会自动加上final,开发者不需要定义final关键字,因为局部变量的生命周期,随着方法调用而存在,随着方法调用完毕而消失,而当前这个局部变量被局部内部类在进行访问(局部内部类对象进行访问),在堆内存中对象不会被立即回收,它还在
继续使用这个局部变量,需要将这个变量定义为常量,常驻内存---->以便局部内部类对象对该局部变量的访问!
class Outer{
private int num = 20 ;
//成员方法
public void method() {
//局部变量
//final int num2 = 50 ; //JDK7以前(包含JDK7)必须加
int num2 = 50 ;//JDK7以后,将局部变量在内存中优化了,自动加上final (内存中就是一个常量!)
//局部内部类
class Inner{
public void show() {
System.out.println(num);
System.out.println(num2);
}
}
//创建局部内部类对象
Inner inner = new Inner() ;
inner.show();
}
}
//测试类
public class Demo{
public static void main(String[] args) {
//创建外部类对象
Outer outer = new Outer() ;
outer.method();
}
}
4.匿名内部类(重点)
1)匿名内部类:它是内部类一种简化方式!
2) 格式:
new 类(可以是具体类,也可抽象类)名/接口名(){
重写方法;
};
3)匿名内部类的好处:
省去了繁杂的代码,不需要定义类里面的子类或者接口的子实现类,写法比较简单!
4) 匿名内部类的本质就是:继承该类或者是实现了该接口的子类对象!
interface Love{
void love() ;
}
//定义一个类
class Demo{
public void function(Love love) {
love.love();
}
}
//定义一个子实现类
class Worker implements Love{
@Override
public void love() {
System.out.println("爱Java...");
}
}
//测试类
public class InnerClassTest2 {
public static void main(String[] args) {
//需要调用PersonDemo类中的function方法
//方法一:(以前的方法,创建了子实现类workers)
PersonDemo pd = new PersonDemo() ;
//接口多态:
Love love = new Worker();
pd.function(love);
System.out.println("---------------------");
//方法二:匿名内部类(不需要创建子实现类)
//接口匿名内部类的使用
PersonDemo pd2 = new PersonDemo()
pd2.function(new Love() {
@Override
public void love() {
System.out.println("爱生活...");
}
});
}
}