Java基础篇:介绍嵌套类和内部类

114 阅读3分钟

在另一个类中定义的类就是嵌套类(nested classes)。嵌套类的范围由装入它的类的范围限制。这样,如果类B被定义在类A之内,那么B为A所知,然而不被A的外面所知。

嵌套类可以访问嵌套它的类的成员,包括private成员。但是,包围类不能访问嵌套类的成员。

嵌套类一般有2种类型:前面加static标识符的和不加static标识符的。一个static的嵌套类有static修饰符。因为它是static,所以只能通过对象来访问它包围类的成员。

也就是说,它不能直接引用它包围类的成员。因为有这个限制,所以static嵌套类很少使用。

嵌套类最重要的类型是内部类(inner class)。内部类是非static的嵌套类。它可以访问它的外部类的所有变量和方法,它可以直接引用它们,就像外部类中的其他非static成员的功能一样。这样,一个内部类完全在它的包围类的范围之内。

下面的程序示例了如何定义和使用一个内部类。名为Outer的类有一个名为outer_x的示例变量,一个名为test()的实例方法,并且定义了一个名为Inner的内部类。

// Demonstrate an inner class. 
class Outer { 
 int outer_x = 100; 
 void test() { 
 Inner inner = new Inner(); 
 inner.display(); 
 } 
 // this is an inner class 
 class Inner { 
 void display() { 
 System.out.println("display: outer_x = " + outer_x); 
} 
 } 
} 
class InnerClassDemo { 
 public static void main(String args[]) { 
  Outer outer = new Outer(); 
  outer.test(); 
 } 
} 

该程序的输出如下所示:

display: outer_x = 100 

在本程序中,内部类Inner定义在Outer类的范围之内。因此,在Inner类之内的任何代码可以直接访问变量outer_x。

实例方法display()定义在Inner的内部,该方法以标准的输出流显示 outer_x。InnerClassDemo的main( )方法创建类Outer的一个实例并调用它的test( )方法。 创建类Inner和display()方法的一个实例的方法被调用。

认识到Inner类只有在类Outer的范围内才是可知的是很重要的。如果在类Outer之外的任何代码试图实例化Inner类,Java编译器会产生一条错误消息。

总体来说,一个嵌套类和其他任何另外的编程元素没有什么不同:它仅仅在它的包围范围内是可知的。

我们解释过,一个内部类可以访问它的包围类的成员,但是反过来就不成立了。内部类的成员只有在内部类的范围之内是可知的,而且不能被外部类使用。例如:

// This program will not compile. 
class Outer { 
 int outer_x = 100; 
 void test() { 
 Inner inner = new Inner(); 
 inner.display(); 
 } 
 // this is an inner class 
 class Inner { 
int y = 10; // y is local to Inner 
void display() { 
 System.out.println("display: outer_x = " + outer_x); 
} 
 } 
 void showy() { 
System.out.println(y); // error,y not known here! 
 } 
} 
class InnerClassDemo { 
 public static void main(String args[]) { 
  Outer outer = new Outer(); 
  outer.test(); 
 } 
} 

这里,y是作为Inner的一个实例变量来声明的。这样对于该类的外部它就是不可知的,因此不能被showy()使用。

尽管我们强调嵌套类在它的外部类的范围之内声明,但在几个程序块的范围之内定义内部类是可能的。例如,在由方法定义的块中,或甚至在for循环体内部,你也可以定义嵌套类,如下面的程序所示:

// Define an inner class within a for loop. 
class Outer { 
 int outer_x = 100; 
 void test() { 
for(int i=0; i<10; i++) { 
 class Inner { 
 void display() { 
 System.out.println("display: outer_x = " + outer_x); 
} 
 } 
 Inner inner = new Inner(); 
 inner.display(); 
} 
 } 
} 
class InnerClassDemo { 
 public static void main(String args[]) { 
  Outer outer = new Outer(); 
  outer.test(); 
 } 
} 

该程序的这个版本的输出如下所示。

display: outer_x = 100 
display: outer_x = 100 
display: outer_x = 100 
display: outer_x = 100 
display: outer_x = 100 
display: outer_x = 100 
display: outer_x = 100 
display: outer_x = 100 
display: outer_x = 100 
display: outer_x = 100 

尽管嵌套类在日常的大多数编程中不使用,但当处理applet(小应用程序)时是特别有帮助的。后面将继续解说,在那里你将看到对于某些类型的事件内部类如何被用来简化代码。你也将了解匿名内部类,它是一个没有名字的内部类。