内部类
定义在一个类中的另一个类叫内部类。内部类的特性如下:
1) 内部类方法可以访问该类定义所在的作用域的数据,包括私有域。
2) 内部类可以对同包下的其他类隐藏。
3) 当想要定义一个回调函数且需要大量代码使用匿名内部类比较便捷。
一个比较典型的链表类,结点时她的内部类:
class LinkedList{
...
public class Iterator
{
...
}
}
使用内部类访问对象状态
我们用一个简单你的例子,来看看内部类与外围类的私有域是在怎样调用的:
interface InterfaceTest{
public void SysInnerId();
}
class Periphera{ //外围类
private int id;
public Periphera(int n){
this.id = n;
}
public void sysInnner(int i){
System.out.println("构造内部类对象");
InterfaceTest it = new InnerClass(i); //直接构造接口InterfaceTest的对象
it.SysInnerId();
}
public class InnerClass implements InterfaceTest{ //内部类
private int innerId;
public InnerClass(int i){
this.innerId = i;
System.out.println("输出外围类的私有域"+id);
}
@Override
public void SysInnerId(){
System.out.println("输出内部类的私有域"+innerId);
}
}
}
public class InnerTest1 {
@Test
public void test(){
Periphera p = new Periphera(1);
p.sysInnner(2);
System.out.println(Periphera.InnerClass.class);
}
}
输出结果:
构造内部类对象
输出外围类的私有域1
输出内部类的私有域2
class InnerClassTest.Periphera$InnerClass
我们可以看出,内部类可以直接访问外围类的私有域,而外围类也可以直接构造内部类。就像内部类中有一个外围类的隐式引用。当我们通过反射输出public修饰的内部类时,虚拟机返回class InnerClassTest.Periphera$InnerClass
局部内部类
上述代码中,外围类的方法sysInnner()中构造了构造并访问了内部类,现在把把内部类删除,将方法sysInnner()改为:
public void sysInnner(int i){
class InnerClass implements InterfaceTest{ //内部类
private int innerId;
public InnerClass(int i){
this.innerId = i;
System.out.println("输出外围类的私有域"+id);
}
@Override
public void SysInnerId(){
System.out.println("输出内部类的私有域"+innerId);
}
}
System.out.println("构造内部类对象");
InterfaceTest it = new InnerClass(i); //直接构造接口InterfaceTest的对象
it.SysInnerId();
}
发现在test()方法中 System.out.println(Periphera.InnerClass.class);
语句报错,删除该语句输出一切照旧。这就是局部内部类。局部类不能被public和private修饰。同时局部类对外部世界完全隐藏,所以语句System.out.println(Periphera.InnerClass.class)报错。它的作用域被限定在声明类的块中,即只有方法 sysInnner()才能访问。
匿名内部类
在局部类的基础上我们再次修改方法sysInnner():
public void sysInnner(int i){
System.out.println("构造内部类对象");
InterfaceTest it = new InterfaceTest(){
@Override
public void SysInnerId() {
System.out.println("输出方法参数"+i);
}
};
it.SysInnerId();
}
结果如下:
构造内部类对象
输出方法参数2
在内部类中单纯实现接口,不需要接口的实现类另外增加实例域和非接口方法是可以在方法中用匿名内部类,因为在匿名内部类中实现接口不能任何构造参数。同时该匿名类的对象也只能作用于该局部方法中。
静态内部类
当内部类仅仅想隐藏在类中,不想获得外围类的引用,就将内部类声明static;称之为静态内部类。