内部类
成员内部类
在一个类中使用内部类,可以直接在内部类中存取其所在类的私有成员变量。
成员内部类的语法如下:
public class OuterClass{
private class innerClass{
//...
}
}
我们可以通过外部类或者外部类的非静态方法来实例化内部类对象,实例如下:
OuterClass out = new OuterClass();
OuterClass.innerClass = out.new innerClass(); //必须在 new 操作符之前提供一个外部类的引用。
// 该方法为非静态方法,必须依赖于外部类的实例而发生调用,所该方法最后一行中 new 关键子等同于 out.new,若该方法为静态方法则会有编译器报错,因为内部类对象必须依赖于外部类对象而存在。
public innerClass doit{
return new innerClass(); //返回内部类的实例的引用
}
向上转型为接口
package Test;
interface OutInterface{ //定义一个接口
public void f();
}
public class OuterClass{
private class innerClass1 implements OutInterface{ //实现接口
public void f(){ //实现 f() 方法
System.out.println("访问内部类 innerClass1 中的f()方法");
}
}
public OutInterface doit(){ //将内部类对象向上转型为接口
return new innerClass1();
}
public static void main(String args[]){
OuterClass out = new OuterClass(); //实例化外部类对象
OutInterface outinter = out.doit(); //调用doit(),放回一个 OutInterface 借口
outinter.f(); //调用内部类innerClass1的f() 方法
}
}
匿名内部类
语法如下:
return new InnerClass(){
//类体
};
说明:匿名内部类编译以后,会产生以“外部类名$序号”为名称的.class 文件,序号以 1~n 排列,分别代表 1~n个匿名内部类。
静态内部类
静态内部类不可以使用外部类的非静态成员,且创建时不需要其外部类对象。
应用:进行程序测试时,如果在每一个 Java 文件中都设置一个主方法,将会出现很多额外的代码,而程序本身不需要这些主方法,为了解决这个问题,可以将主方法写入静态内部类中。
public class StaticInnerClass{
int x = 100;
static class InnerClass{
void doitInner(){
// System.out.println("外部类"+x);
}
public static void main(String args[]){
System.out.println("a");
}
}
}
编译该类,将生成一个名称为StaticInnerClass$InnerClass
的独立类和一个 StaticInnerClass
类,只要使用 java StaticInnerClass$Inner
,就可以运行主方法中的内容,这样当测试完成,需要将所有的.class文件打包时,只要删除 StaticInnerClass$InnerClass
即可。
内部类的继承
内部类的继承比继承普通类复杂,需要设置专门的语法来完成。
public class OutputInnerClass extends ClassA.ClassB{
public OutputInnerClass(ClassA a){
a.super();
}
}
class ClassA{
class ClassB{
}
}
在某个类继承内部类时,必须硬性给予这个类一个带参数的构造方法,并且构造方法参数为需要继承内部类的外部类的引用,同时在构造方法体中使用 a.super() 语句,这样才为继承提供了必要的对象引用。