如果在类中定义了一个类,那么在类中再定义的那个类叫做内部类。
为什么要使用内部类?
1、内部类可以访问该类所在作用域中的数据,包括私有的数据;
2、内部类可以对同一个包中的其他类隐藏起来;
成员内部类
成员内部类是直接在类的定义域中定义的类,内部类中可以直接使用外部类的成员变量和方法,尽管它们都是private修饰的,但是内部类的成员只有在内部类的范围之内有效,不能在外部类使用。
我们可以直接在外部类和外部类的非静态方法中直接构造一个内部类,但是在外部类和外部类非静态方法之外通过内部类构造器实例化内部类对象时,需要提供一个外部类的引用。
例如:
public class OuterClass {
private int num;
InnerClass in = new InnerClass();//在外部类中可以实例化内部类对象
public class InnerClass {
int num1;
public void inFunction() {
System.out.println("外部成员变量num = " + num);//内部类可以调用
System.out.println("内部类方法");
outFunction();//内部类可以直接调用外部类的方法
}
}
public void outFunction() {
// num1 = 0;//外部类不能直接访问内部类的成员变量
// inFunction();//外部类不能直接调用内部类方法
System.out.println("外部类方法");
}
public InnerClass getInnerObject() {
return new InnerClass();
}
public static void main(String[] args) {
OuterClass out = new OuterClass();
OuterClass.InnerClass in = out.getInnerObject();
OuterClass.InnerClass in1 = out.new InnerClass();
}
}
类与类之间有三种关系:依赖(“use-a”)、聚合(“has-a”)和继承(“is-a”),我们可以看到外部类聚合了内部类,内部类同时又依赖于外部类。
局部内部类
内部类不仅可以在类中进行定义,也可以在类的局部位置定义,如在类的方法或任意的作用域中均可以定义内部类。
如果内部类定义在一个方法体内部时,该方法的外部不能访问到内部类,但是内部类可以访问该方法中的常量和以及此外部类的所有成员。
例如:
public class OuterClass {
int num;
// InnerClass in = new InnerClass();//在方法外不能访问到局部内部类
public void outFunction(final int n) {
// num1 = 0;//外部类不能直接访问内部类的成员变量
// inFunction();//外部类不能直接调用内部类方法
System.out.println("外部类方法");
class InnerClass {
public void inFunction() {
num = n;//内部类可以访问方法中的常量
System.out.println("外部成员变量num = " + num);//内部类可以访问外部类的成员变量
System.out.println("内部类方法");
}
}
}
}
匿名内部类
匿名内部类是没有名字的内部类,这种内部类的作用实际上创建一个实现于某个接口的匿名类对象。
例如:
interface InnerClass{}
public class OuterClass {
private int num;
public InnerClass getInnerObject() {
return new InnerClass() {
int num1 = num;
public void showValue() {
System.out.println(num1);
}
};
}
}
静态内部类
静态内部类是在内部类前添加static关键字修饰,一个静态类内部可以声明static成员,但是非静态类内部不可以声明静态成员。
由于静态内部类中不能访问外部类的非静态成员,所以静态内部类在实际的开发中比较少见。