一、内部类的种类及特点
1.成员内部类
public class OuterClass {
public class InnerClass {
}
}
2.静态内部类(只有内部类才能被静态修饰符所修饰)
public class OuterClass {
public static class InnerClass {
}
}
3.匿名内部类
public class OuterClass {
Runnable thread = new Runnable() {
@Override
public void run() {
System.out.println("hello world");
}
};
}
-
无需单独创建类文件去实现接口,或者继承父类,简化代码
二、内部类的编译
1.成员内部类
-
成员内部类编译过程中会生成一个独立于外部类的字节码文件,其名称格式: 外部类名 + $ + 内部类名.class
2.静态内部类
-
静态内部类与成员内部类相似,产生一个独立于外部类的字节码文件,名称格式如上
-
静态类之所以能访问外部类的静态成员变量,是因为在编译过程中,为外部类的静态成员变量提供了一个静态的入口方法,通过调用该静态入口方法,便能访问到外部类的静态成员变量
3.匿名内部类
-
匿名内部类编译过程中也会生成一个独立于外部类的字节码文件,但是它的命名格式与非匿名内部类不同,因为它没有类名,所以生成的字节码文件名称格式:外部类名 + $ + 数字.class (数字从1开始累加)
三、内部类的意义
1.实现多继承
-
Java多实现、单继承语言,利用内部类填补了多继承的空缺,例如:封装类有多个内部类,它们分别继承不同的父类,然后封装类内部调用内部类的实例便同时拥有了多个父类的全部属性
2.简化代码
-
我们无需为内部类单独创建一个单独的类文件,简化了我们的代码
3.无需修改而实现同一个类中两个同名同参的方法调用
-
当我们的类中有一个与所需实现接口同名同参的方法时,可用内部类实现该接口,再利用内部类的特性调用类中方法,实现同一个类对两个同名同参方法的调用
public class Frog {
String move(int mile) {
Tadpole tadpole = new Tadpole();
String tm = tadpole.move(mile / 2);
return "Frog move " + mile + " and " + tm;
}
class Tadpole implements Animal{
@Override
public String move(int mile) {
return "Tadpole move " + mile;
}
}
}
总结:如果没有非常好的把控能力,一般不提倡使用内部类;而且内部类几乎都是基于服务外部类而存在,一般不推荐实例化内部类,这样违背了面向对象设计的原则,破坏了类的封装性