内部类:把类定义在另一个类里面
public class Outer { //外部类
private class Inner{ //内部类
}
}
内部类的分类
(1)成员内部类 :定义在类里,方法外,作为外部类的成员而存在
成员内部类基本特征
- 内部类可以直接访问外部类的成员
- 外部类不可以直接访问内部类的成员,必须先创建对象再使用
- 外部类只能使用public和默认修饰,而内部类因为是类的成员,所以可以用四个修饰符修饰
public class Outer { //外部类
private String name="张三";
class Inner{
public void show(){
System.out.println("name="+name);
}
}
}
测试
public class Test {
public static void main(String[] args) {
Outer o=new Outer(); //o是Outer的对象名
Outer.Inner i=o.new Inner(); //对象名.
i.show();//内部类的对象名.方法名
}
}
(2)静态内部类 :在成员内部类的基础上添加static
public class Outer {
private static String name="张三"; //对象的
static class Inner{ //静态内部类
public void show(){
System.out.println("name="+name);
}
}
static class Inner2{ //如果内部类中的方法为静态的,那么这个内部类必须为静态内部类
public static void show(){
System.out.println("name="+name);
}
}
}
测试
public class Test {
public static void main(String[] args) {
Outer.Inner i=new Outer.Inner();//创建的是内部类的对象
i.show(); //内部类的对象名.方法名();
Outer.Inner2.show(); //外部类的类名.内部类的类名.静态方法名
}
}
(3)方法中的内部类
JDK1.8之前,方法中的内部类不允许使用外部的变量的,只能使用外部类的常量
public class Outer {
public void show(final int a){ //方法
//方法中的类不允许使用修饰符,因为局部变量没用修饰符的概念
class Inner{ //Inner是给show方法做局部变量
public void fun(){
System.out.println("a="+a);
}
} //Inner是show方法中的局部变量,所以它的生命周期只限于show方法
Inner i=new Inner();
i.fun();
}
}
JDK1.8开始,方法中的内部类允许使用外部类的变量
public class Outer {
public void show(int a){ //方法
//方法中的类不允许使用修饰符,因为局部变量没用修饰符的概念
class Inner{ //Inner是给show方法做局部变量
public void fun(){
System.out.println("a="+a);
}
} //Inner是show方法中的局部变量,所以它的生命周期只限于show方法
Inner i=new Inner();
i.fun();
}
}
测试
public class Test {
public static void main(String[] args) {
Outer o=new Outer();
o.show(10);
}
}
(4)匿名内部类
要求:必须存在继承或实现关系
public class Test {
public static void main(String[] args) {
String [ ]arr={"orange","banana","pear","apple","grape","peach"};
System.out.println("排序前:"+Arrays.toString(arr));
Arrays.sort(arr);//排序
System.out.println("排序后:"+Arrays.toString(arr));//a,b,....z
//希望排序可以换一种方式,换成按照字母的个数排
Arrays.sort(arr, new Comparator()
{//这对没有名称的{}就是Comparator接口的实现类,由于这个类没有名称,叫匿名
@Override
public int compare(Object o1, Object o2) {
String s1=(String)o1;
String s2=(String)o2;
return s1.length()-s2.length();
}
}
);
System.out.println("排序后:"+Arrays.toString(arr));
}
}
- 匿名内部类可以实现一个接口,也可以继承一个抽象类
- 匿名内部类只能实现一个接口,而不是多个
- 必须实现所有的方法,匿名内部类不能是抽象类
- 匿名内部类不可能有构造方法,因为类是匿名的
- 如果想实现构造方法的一些初始化功能,可以通过代码块实现