1、内部类向上转型为接口
outclass2类定义了一个private的内部类,这个内部类实现了outFace接口,然后修改doit(),使其返回一个outFace接口。由于内部类innerclass的修饰符为private,所以外部类及其他类都不能访问,只有内部类访问,然后实现接口中的f()方法。这里很好的对继承该类的子类隐藏了实现细节,仅仅留下一个接口和一个外部类,同时也可以调用f(),但是细节却被很好的隐藏了,这就是内部类最基本的用途。
注意:非内部类不能被修饰为private和protected。
package a1;
interface OutFace{
public void f();
}
public class InterFace
{
public static void main(String[] args)
{
OutFace2 out=new OutFace2();
OutFace outinter=out.doit();
outinter.f();
}
}
class OutFace2
{
private class InnerClass implements OutFace
{
InnerClass(String s)
{
System.out.println(s);
}
public void f()
{
System.out.println("访问内部类中的f()方法");
}
}
public OutFace doit()
{
return new InnerClass("访问内部类构造方法");
}
}
2、局部内部类
这里一样遵循内部类可以访问当前代码的常量以及此外部类的所有成员,但是doit()的外部类不能访问该内部类。此处注意doit()的参数设置为final类型,换句话说,包含内部类的方法中使用局部变量都要设置为final,在方法中定义的内部类只能访问方法中final类型的局部变量,这是因为在方法定义中定义的局部变量相当于一个常量,它的生命周期超出方法运行的生命周期,由于该局部变量设置为final,所以不能再内部类中改变该局部变量的值。
package a1;
interface OutFace2
{
}
class OutClass {
public OutFace2 doit(final String x)
{
class InnerClass implements OutFace2
{
InnerClass(String s)
{
s=x;
System.out.println(s);
}
}
return new InnerClass("doit");
}
}
3、匿名内部类
通过把return和内部类的定义语句结合在一起,这里A是类名,这种写法虽然莫名奇妙,但是能被java所认可,由于这个类没有名称,所以该内部类被称为匿名内部类。实质上这种内部类的作用就是创建一个实现于A接口的匿名类的对象。
注意,这里花括号后面加分号,这个分号并不是代表定义内部类结束,而是代表创建A引用表达式的标志。
匿名内部类编译后,会产生 外部类名$序号 为名称的.class文件,序号以1~n排列,分别代表1~n个匿名内部类。
return new A()
{
//内部类体
};
4、静态内部类
在内部类前面声名static,静态内部类的最大特点是不可以使用外部类的非静态成员,所以静态内部类很少见。
5、内部类的继承
内部类一样可以被继承,但是内部类的继承更复杂,需要专门的语法来实现。在继承某个内部类时,必须硬性的给这个类一个带参数的构造方法,并且该构造方法的参数为需要继承内部类的外部类的引用,同时在构造中使用 a.super(); 语句,才能为继承提供必要的对象引用。
public class OutClass extends ClassA.ClassB
{
public OutClass(ClassA a)
{
a.super();
}
}
class ClassA
{
class ClassB
{
}
}
这些是复习时的随笔。