内部类:封装的第三种形式(函数和属性私有化)
方法内部类在编译之后生成的class文件,
命名是:外部类名$编号内部类名(编号是从1开始,按照顺序依次往下)这是从文件区分方法内部类的关键
成员内部类在编译之后生成的class文件,命名是:外部类名$内部类名
静态内部类在编译之后生成的class文件,命名是:外部类名$内部类名
方法内部类
定义在方法中的类
1.方法内部类只能在定义它的方法内使用。相当于局部变量。不能在方法外使用。
2.方法内部类不允许定义静态变量和静态方法,但是可以定义静态常量(此时的静态常量属于整个外部类,却不属于内部类。但是外部类不可以调用)
3.方法内部类不能使用当前方法内的局部变量,如果想使用这个量必须是一个常量
4.方法内部类可以直接使用外部类的属性和方法。
除了以上几点,方法内部类跟外部类的使用方法一致,可以继承、可以实现等
成员内部类
成员内部类定义在类内、方法外
成员内部类的对象需要利用外部类对象来创建
成员内部类中不允许定义静态变量和静态方法,但是可以定义静态常量
其他使用方法和一般的类一致。
//在类外创建内部类对象
Outer2.Inner2 oi22 = new Outer2().new Inner2();
静态内部类
用static修饰的成员内部类。
可以认为这个类是一个普通的类,不完全依赖于外部类
静态内部类不可以使用外部类的成员变量和普通方法,但是可以使用静态变量和静态方法。
静态内部类中可以定义静态变量和静态方法
Outer3.Inner3 oi3 = new Outer3.Inner3();
匿名内部类
匿名内部类本质上是继承了外部类或者实现了对应接口
①当匿名内部类定义在方法内的时候,需要注意的地方和方法内部类一样。(与方法内部类唯一的区别是因为没有名字而不能定义构造函数)本质上还是有构造函数的,JVM在底层编译的时候会自动添加。只是不能手动添加而已。
②当匿名内部类定义在类里面方法外面的时候,需要注意的地方和成员内部类一样。
抽象类和接口都可以写成匿名内部类的形式:
接口类型 变量名 = new 接口类型(){重写}
抽象类型 变量名 = new 抽象类型(){重写}
在匿名内部类中可以定义自己特有的方法,但是一般是不会定义的,因为即使定义了,也几乎用不到。(匿名内部类的使用的是向上造型,父类引用指向子类对象,只能调用父类已有的方法,不可以使用子类特有的对象)
内部接口
定义在类内或者接口内的接口
接口中可以定义类或者接口,而且默认也是静态的。
为什么内部接口默认是静态的?
当接口定义在类内:如果内部接口不是一个静态的,此时就相当成员内部类,调用接口的时候需要使用一个外部类的对象,但是声明类实现这个接口的时候是无法创建对象的。而静态的不需要类便可以直接调用。
当接口定义在接口内:若不是静态的,接口不能创建对象,
接口内可以定义类,并且这个类默认是静态内部类。