Java语言中的内部类
内部类(Inner Class)是指将一个类定义在另外一个类的内部,甚至是一个方法的内部。包含内部类的类称为外部类(Outer Class)或顶层类(Top-level Class),内部类则被看出是外部类的一个成员,也称之类的嵌套。作为一个成员,它有如下特点:
l 若使用Static修饰,则为静态内部类;否则为非静态内部类。
l 使用static修饰的目的,是为了让内部类和外部类的对象独立
【例5.15】外部类定义代码
class Outer
{
static int outer_s=900;
int outer_x=100;
void text()
{
Inner inner=new Inner();
inner.display();
}
static class Inner
{
void display()
{
System.out.println("输出外部类静态成员:outer_s="+outer_s);
}
}
}
下边再看一个测试程序。
【例5.16】测试程序Example5_16代码实现
public classExample5_15
{
public static void main(String args[])
{
Outer outer=new Outer();
outer.text();
Outer.Inner inter=new Outer.Inner();
inter.display();
}
}
编译Outer.java和Example5_16.java程序,系统在当前目录下生成了3个类Outer.class、Outer$Inner.class和Example5_15.class。运行测试程序,可以看到两个输出结果是一样的。
输出外部类静态成员:outer_s=900
输出外部类静态成员:outer_s=900
静态和非静态内部类的主要区别在与:
(1)静态类对象和外部类对象独立。它可以直接创建对象(如new Outer.Inner())也可通过外部类对象创建(如上例中,在外部对象的test()方法中创建)。非静态类对象不能和外部类对象独立,它只能由外部对象创建。
(2)静态类中只能使用外部类的静态成员。不能使用外部类的非静态成员。非静态类中可以使用外部类的所有成员。
(3)在静态类可以定义静态和非静态成员。在非静态类中只能定义非静态成员,不能定义静态成员。
了解了上述的区别之后,可以将上例中的静态内部类修改为非静态内部类,然后再修改测试程序,编译它们、运行测试程序。看一下它们之间的差别。
注意:
(1)由于内部类的成员属于该内部类,因此,外部类不能直接存取内部类的成员。只有通过内部类才能访问内部类的成员。
(2)与外部类不同,内部类可用private修饰。
(3)如果将一个内部类定义在一个方法内(本地内部类),它完全可以隐藏在方法中。甚至同一个类的其他方法也无法使用它。
【例5.17】在方法内定义一个内部类。
class OuterA
{
int outer_x=100;
void text()
{
class Inner
{
void display()
{
System.out.println("display:outer_x="+outer_x++);
}
}
for(int i=1;i<5;i++)
{
Innerinner=newInner();
inner.display();
}
}
}
public classExample5_17 {
public static void main(String args[])
{
OuterAouter=newOuterA();
outer.text();
}
}
编译、运行测试程序,结果如下:
display:outer_x=100
display:outer_x=101
display:outer_x=102
display:outer_x=103
Java语言中的匿名类(没有类名的内部类)
匿名类(Anonymouse Class)是一种没有类名的内部类,多用在事件处理的程序中。有时用户需要定义一个类,且只想在程序中定义该类的一个对象,并把它作为参数传递给一个方法。只要该类是一个现有类的派生或实现一个接口,就可以使用匿名类。匿名类定义短而简单且使用方便,但不易过多使用,它会引起程序代码的复杂化而不易理解。
下面通过一个简单示例,说明匿名类的实现情况。例如,关闭窗口(单击关闭按钮)、单击鼠标等。
【5.18】匿名类的使用
import java.applet.*;
import java.awt.event.*;
public classExample5_18 extends Applet
{
static int counter;
public void init()
{
counter=0;
addMouseListener(new MouseAdapter()
{
public void mousePressed(MouseEventme)
{
counter++;
showStatus("你单击了"+counter+"次鼠标!");
}
}
);
}
}
在上面程序中,类定义出现在表达式中,该式生成要传递给addMouseListener()方法的参数,该方法要求MouseAdapter类型的一个引用。类的详细定义出现在“{}”中,匿名类中可以包含数据成员和方法,在本类中它包含一个实现MouseListener接口的mousePressed()方法。