1. 定义
如果在一个类中再定义一个类,再定义的类称为内部类。
语法如下:
public class OuterClass { //外部类 private class InnerClass { //内部类 //... } }
内部类可以随意使用外部类的成员方法和成员变量,包括修饰为private的方法和变量,但外部类不能直接使用内部类的成员变量和方法。
public class OuterClass {
private int x=2;
innerClass in = new innerClass(); //在外部类中实例化内部类对象引用
public void out(){
in.inf(); //在外部类方法中调用内部类方法
}
class innerClass {
innerClass(){ //内部类构造方法
}
public void inf(){ //内部类成员方法
}
int y=0; //内部类成员变量
int z=x; //内部类中直接使用外部类的成员变量
}
public innerClass doit() { //外部类方法,返回值为内部类引用;
//y=4; //外部类不能直接访问内部类成员变量
in.y=4; //调用内部类对象访问内部类成员变量
return new innerClass(); //返回内部类引用
}
public static void main(String args[]){
OuterClass out = new OuterClass();
//内部类的对象实例化操作必须在外部类或外部类的非静态方法中实现
OuterClass.innerClass in=out.doit();
OuterClass.innerClass in2=out.new innerClass(); //实例化内部类对象
}
}
内部类的对象实例化操作必须在外部类或外部类的非静态方法中实现。换句话说,内部类对象依赖于外部类对象,必须通过外部类对象来创建其内部类对象。
2.内部类向上转型为接口
使用内部类实现接口。
来看代码例子:
interface OutInterface {
public void f();
}
public class InterfaceInner {
public static void main(String args[]){
OuterClass out = new OuterClass(); //实例化一个OuterClass对象
//调用doit()方法,返回一个OutInterface接口
OutInterface outinner = out.doit();
outinner.f(); //调用内部类的f()方法
}
}
class OuterClass {
//定义一个内部类实现OutInterface接口
private class innerClass implements OutInterface {
innerClass(String s) { //内部类构造方法
System.out.println(s);
}
public void f() { //实现接口中的f()方法
System.out.println("访问内部类中的f()方法");
}
}
public OutInterface doit() { //定义一个方法,返回值类型为OutInterface接口
return new innerClass("访问内部类构造方法");
}
}
结果:
访问内部类构造方法
访问内部类中的f()方法
上述代码就是定义了一个private权限的内部类并实现接口。由于内部类权限为private,所以除了它的外部类OuterClass可以访问该内部类其它类都不能访问,但其它类可以访问doit()方法,同时由于该方法返回一个外部接口类型,该接口可以作为外部使用的接口,接口的f()方法可供外部调用,但具体实现过程是在内部类中,这种对外隐藏实现过程增加了代码的可维护性和安全性。
3.局部内部类及匿名内部类
局部内部类指的是将内部类定义在方法内部。这样方法外部不能访问该内部类,但该内部类可以访问当前代码块的常量及外部类的所以成员。
例如:
interface OutInterface {
//...
}
class OuterClass {
public OutInterface doit(final String x) {
//在doit方法内定义一个内部类
class innerClass implements OutInterface {
innerClass(String s) { //内部类构造方法
s = x;
System.out.println(s);
}
}
return new innerClass("doit方法");
}
}
匿名内部类
匿名类的所有实现代码都需要在大括号之间进行编写,语法如下:
return new A(){ ...//内部类体 };
主要用于创建匿名类的对象。来看例子:
interface OutInterface {
}
class OuterClass {
public OutInterface doit() { //定义doit方法
return new OutInterface() { //声明匿名内部类
private int i=0;
public int getValue() {
return i;
}
};
}
}