一、嵌套类和内部类的说明
可以在类的内部定义另外一个类,这种类就是所谓的嵌套类。嵌套类的作用域被限制在包含它的类之中。因此,如果类B是在类A中定义的,那么类B不能独立于类A存在。嵌套类可以访问包含它的类的成员,包括私有成员,但是包含类不能访问嵌套类的成员。嵌套类直接在包含类中作为成员进行声明。也可以在代码块中声明嵌套类。
嵌套类有两种类型:静态的和非静态的,静态的嵌套类是应用了static修饰符的嵌套类,因为是静态的,所以只能通过对象访问包含类的非静态成员。也就是说,嵌套类不能直接引用包含类的非静态成员。因为这条限制,所以很少使用静态的嵌套类。
嵌套类最重要的类型是内部类,内部类是非静态的嵌套类,可以访问外部类的所有变量和方法,并且可以直接引用它们,引用方式与外部类的其他非静态成员使用的方式相同。
public class Outer {
private String outerName = "This is Outer Name";
public void test() {
Inner inner = new Inner();
inner.display();
}
public class Inner {
public void display() {
System.out.println(outerName);
}
}
}
测试:
public class Test {
public static void main(String[] args) {
Outer outer = new Outer();
outer.test();
}
}
在这个程序中,被命名为Inner的内部类是在Outer类的作用域内定义的。所以,Inner类中的所有代码,都可以直接访问变量OuterName。在Inner类中定义了一个名为display()的实例方法,该方法输出outerName,Test类中创建了Outer类的一个实例,并调用这个实例的test(),该方法会创建一个Inner类的实例,并调用display()。
只能在Outer类的作用域内创建Inner类的实例,认识到这一点很重要。如果试图在Outer类之外的任何代码中实例化Inner类,java编译器会产生错误,一般来说,必须通过封闭的作用域来创建内部类的实例。
正如所解释的,内部类可以访问外部类的所有成员,但是反过来不可以。内部类的成员只有在内部类的作用域内才是已知的,并且外部类不能使用。
public class Outer {
private String outerName = "This is Outer Name";
public void test() {
Inner inner = new Inner();
inner.display();
}
public void showInnerName() {
System.out.println(innerName); //错误
}
public class Inner {
String innerName = "This is innerName";
public void display() {
System.out.println(outerName);
}
}
}
在上面中,innerName被声明成Inner类的实例变量,因此,在Inner类的外部不知道innerName,并且showInnerName()也会报错。
尽管我们一直主要关注的是:在外部类的作用域内作为成员声明的内部类,但是也可以在任何代码块的作用域内定义内部类。例如,可以在由方法定义的代码块中,甚至在for循环体内定义嵌套类。
public class Outer {
private String outerName = "This is Outer Name";
public void test() {
for(int i=0;i<3;i++) {
class Inner {
public void display() {
System.out.println(outerName);
}
}
Inner inner = new Inner();
inner.display();
}
}
}
在上面的代码中,只能定义成class inner,不能定义成public class inner,因为此时是作为方法中的变量定义的,不是作为类的成员变量。
尽管嵌套类并不是对于所有的情况都适用,但是当处理事件时它们特别有用。