1、内部类
定义在其他类内部的类被称为内部类
- 内部类提供了更好的封装,不允许同一包的其他类访问
- 内部类成员可以访问外部的私有数据
- 匿名内部类适用于创建仅需要使用一次的类
定义与普通类的区别
1. 内部类比外部类可以使用三个修饰符:private,protected,static
2. 非静态内部类不可以有静态成员
2.非静态内部类
大部分内部类都被作局部内部类为成员内部类定义,而不是作为局部内部类。成员内部类与类的变量、方法、构造器相类似的类成员;局部内部类和匿名内部类不是类成员。
外部类的上一级程序单元是包,所以它只有2个作用域;而内部类的上一级程序单元是外部类所以他的作用域范围有4个
public class Outer {
private int outProp=9;
//定义非静态内部类
class Inner{
private int inProp=5;
public void accessOuterProp(){
System.out.println("外部类的outProp:"+outProp);
}
}
public void accessInnerProp(){
//创建内部类实例,并访问其的内部类的属性
System.out.println("内部类的inProp:"+new Inner().inProp);
}
public static void main(String[] args) {
Outer d=new Outer();
d.accessInnerProp();
}
}
非静态内部类的方法访问某个变量时的顺序为:局部变量->内部类的成员变量->外部类的成员变量。
如果遇到外部类的成员变量、内部类的成员变量和内部类方法的局部变量名相同时,可以通过使用this、外部类类名.this来区分
非静态内部类的成员不能直接被外部类直接使用,只能通过实例化内部类来实现
根据静态成员不能访问非静态成员规则,外部类静态成员方法、静态代码块不能访问非静态内部类
public class Outer{
class Inner{
private int inProp=5;
public void accessOuterProp(){
System.out.println("外部类的outProp:"+outProp);
}
}
public static void main(String[] args) {
Demo1 d=new Demo1();
d.accessInnerProp();
//此处会发生编译错误,因为在外部静态方法中访问了非静态内部类
Inner i=new Inner();
}
}
非静态内部类不能有静态方法、静态成员变量、静态初始化块
3.使用内部类
- 在外部类内部使用内部类。不要在外部类的静态成员中使用非静态内部类,因为静态成员不能访问非静态成员
- 在外部类以外使用非静态内部类。在外部类以外使用内部类,内部类完整类名应该是OuterClass.InnerClass。如果外部类有包名,则应该增加包名前缀。内部类的构造器必须使用外部类对象来调用
Out.In in=new Out().new In();
当一个SubClass类继承类Out外部类的Inner内部类
public SubClass(Out out){
out.super();
}
在外部类以外使用静态内部类
Out.Inner in=new Out.Inner();
4.匿名内部类
- 只需要使用一次的
- 创建匿名内部类时会立即创建该类的实例,这个类的定义会立即消失
- 匿名类不能重复使用
语法格式:
new 实现接口()|父类构造器(实参列表)
{
//匿名内部类的类体部分
}
匿名内部类必须继承一个父类,或实现一个接口,但最多只能继承一个父类,或实现一个接口
匿名内部类的两条规则:
- 匿名内部类不能是抽象类。因为系统在创建一个匿名内部来时,会立即创建匿名内部类对象
- 匿名内部类不能定义构造器。由于匿名内部类没有类名,所以不能定义构造器