前言
Java内部类是很重要的一块知识,在这里总结一下。内部类分为普通内部类、静态内部类、匿名内部类和局部内部类四种,下面我们依次介绍他们的特点和使用方法。(为了介绍方便,将外部类标号为S类,内部类依次为A、B、C、D)
普通内部类
最常见的一种,在类体中定义一个类就构成了普通内部类(非静态),内部不能定义静态的成员变量/方法。
普通内部类可以直接访问外部类所有权限的成员成员变量和方法。
因为普通内部类相当于外部类的成员,所以是和外部类对象相关的。因此在其他类中想要调用内部类的成员变量/方法,首先要有一个外部类的对象。
public class S {
//外部类全部访问权限的成员变量
public int a = 1;
protected int b = 2;
int c = 3;
private int d = 4;
//外部类构造方法
public S(){
//获得内部类的对象
A temp = new A();
//访问内部类全部权限的成员变量
System.out.println("内部类的成员变量"+"aInner"+"的值为"+ temp.aInner);
System.out.println("内部类的成员变量"+"bInner"+"的值为"+ temp.bInner);
System.out.println("内部类的成员变量"+"cInner"+"的值为"+ temp.cInner);
System.out.println("内部类的成员变量"+"dInner"+"的值为"+ temp.dInner);
}
public class A{
public int aInner = 1;
protected int bInner = 2;
int cInner = 3;
private int dInner = 4;
//内部类方法
public A(){
//直接访问外部类全部权限的成员变量
System.out.println("外部类的成员变量"+"a"+"的值为"+ a);
System.out.println("外部类的成员变量"+"b"+"的值为"+ b);
System.out.println("外部类的成员变量"+"c"+"的值为"+ c);
System.out.println("外部类的成员变量"+"d"+"的值为"+ d);
}
}
}
public class Test {
public static void main(String[] args){
//首先获得外部类的对象
S s = new S();
//然后获得内部类对象
S.A a = s.new A();
}
}
外部类成员变量被读取两次是因为调用了两次内部类的构造方法。
静态内部类
普通内部类被static修饰就构成了静态内部类。和静态成员一样,静态内部类也是独立于外部类所有对象的。
静态内部类可以访问外部类的静态成员,不可以访问非静态成员(独立于对象)。外部类可以通过内部类对象可以访问静态内部类所有成员。
静态内部类创建对象不需要外部类对象。
可以拥有静态成员。
public class S {
//外部类全部访问权限的成员变量
public static int a = 1;
protected int b = 2;
int c = 3;
private int d = 4;
//外部类构造方法
public S(){
//获得内部类的对象
A temp = new A();
//访问内部类全部权限的成员变量
System.out.println("内部类的成员变量"+"aInner"+"的值为"+ temp.aInner);
System.out.println("内部类的成员变量"+"bInner"+"的值为"+ temp.bInner);
System.out.println("内部类的成员变量"+"cInner"+"的值为"+ temp.cInner);
System.out.println("内部类的成员变量"+"dInner"+"的值为"+ temp.dInner);
//访问内部类静态成员变量
System.out.println("内部类的静态成员变量"+"eInner"+"的值为"+ temp.eInner);
}
public static class A{
public int aInner = 1;
protected int bInner = 2;
int cInner = 3;
private int dInner = 4;
//静态成员
static int eInner = 5;
//内部类方法
public A(){
//直接访问外部类全部权限的成员变量
System.out.println("外部类的成员变量"+"a"+"的值为"+ a);
//编译错误
// System.out.println("外部类的成员变量"+"b"+"的值为"+ b);
// System.out.println("外部类的成员变量"+"c"+"的值为"+ c);
// System.out.println("外部类的成员变量"+"d"+"的值为"+ d);
}
}
}
public class Test {
public static void main(String[] args){
//直接获得内部类对象
S.A a = new S.A();
//获得外部类的对象
S s = new S();
}
}
匿名内部类
适用于某接口/抽象类的实现类/子类对象只需要使用一次的情况。
匿名内部类相当于该接口/抽象类的实现类/子类,需要在类体中重写全部抽象方法。
因为匿名内部类没有名字,外部类无法获得其成员变量。
通过”接口名 对象名 = new 接口名(){ 重写所有抽象方法 };“ 的方式实现。
//自定义接口
public interface temp{
int eat();
}
public class Test {
public static void main(String[] args){
//获得自定义接口的实现类的对象
temp t = new temp() {
//自定义成员变量只可在当前类中使用
int a = 1;
@Override
public int eat() {
return a;
}
};
}
}
局部内部类
定义在方法内部的类,使用情况较少,且其用处均可被匿名内部类代替,不展开讲述。