一、内部类:定义在类中的类,就叫内部类
特点就是内部类可以访问外部类的成员,包括私有成员。
内部类分为成员内部类和局部内部类:
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{@Overridepublic 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() { @Overridepublic void love() {System.out.println("爱生活...");}}); }
}