在 Java 中每一个定义好的类,在编译后都会以一个扩展名为 .class 的文件存储下来。在 Java 中通常使用包以层次方式来管理类文件。
1、內嵌类
在类中还可以再定义类,称之为內嵌类(Inner Class)或嵌套类(Nested Class)。非静态的内嵌类可以分为三种:成员內嵌类(Member Inner Class)、区域內嵌类(Local Inner Class)和匿名內嵌类(Anonymous Inner Class),內嵌类的主要目的,就是对外部隐藏类的存在性。
1)成员內嵌类和区域內嵌类
使用內嵌类的好处:其一是內嵌类可以直接存取其所在类中的私有成员;其二是当某个 Slave 类完全只服务于一个 Master 类时,可以将之设定为內嵌类,这样使用 Master 类的人就不知道 Slave 类的存在;再者,像在“静态工厂”(Static Factory)模式中,对调用静态方法的对象隐藏返回对象的实现细节或产生方式。
成员內嵌类时在一个类中直接声明一个类。例如:
public class OuterClass{
//內嵌类
private class InnerClass{
// ...
}
}
成员內嵌类同样可以使用public、protected 或 private 来修饰其存取权限。
EX9.1 PointDemo.java
public class JavaNotesChap0901_PointDemo
{
private class Point
{
public int x;
public int y;
public Point()
{
}
public void setPoint(int x, int y)
{
this.x = x;
this.y = y;
}
public int getX()
{
return x;
}
public int getY()
{
return y;
}
}
Point[] points;
public JavaNotesChap0901_PointDemo(int length)
{
points = new Point[length];
for(int i = 0; i < points.length; i++)
{
points[i] = new Point();
points[i].setPoint(i*5, i*5);
}
}
public void showPoints()
{
for(int i = 0; i < points.length; i++)
{
System.out.printf("Points[%d]: x = %d, y = %d\n", i, points[i].getX(), points[i].getY());
}
}
}
程序中假设 Point 类只服务于 PointDemo 类,外界不必知道 Point 类的存在,只要知道如何实现 PointDemo 的实例就可以了。
EX9.2 PointShow.java
public class JavaNotesChap0901_PointShow
{
public static void main(String[] args)
{
JavaNotesChap0901_PointDemo demo = new JavaNotesChap0901_PointDemo(5);
demo.showPoints();
}
}
在文件管理方面,成员內嵌类在编译完成之后,所产生的文件名为“外部类名称$內嵌类名称.class“。
区域內嵌类的使用与成员內嵌类类似。区域內嵌类定义于一个方法中。类的可视范围与生成的对象仅限于该方法中。
2)匿名內嵌类
內嵌匿名类可以不声明类名称,而使用 new 直接产生一个对象,它可以是继承某个类或是实现某个接口。其声明方式如下:
new [类或接口()]{
//实现
}
一个使用內嵌匿名类的例子如下所示,它直接继承 Object 类定义一个匿名类,重新定义 toString() 方法,并使用匿名类直接产生一个对象。
EX9.3 AnonymousClassDemo.java
public class JavaNotesChap0902_AnonymousClassDemo
{
public static void main(String[] args)
{
final int i = 10;
Object obj = new Object()
{
public String toString()
{
return "AnonymousClass Object " + String.valueOf(i);
}
};
System.out.println(obj);
}
}
使用 System.out.println() 时如果传入的时对象,会调用对象的 toString() 方法得到 String 实例。
注意,如果要在內嵌类中使用外部的区域变量,变量在声明时必须为 final,否则在进行编译时,编译器会报错。
在文件管理方面,內嵌匿名类在编译完成之后产生“外部类名称$编号.class“,编号为 1、2、3、...、n,每个编号 n 的文件对应第 n 个匿名类。
2、package 与 import
1)设定包(Package)
Java 提供包来管理类,包被设计与文件系统结构相对应,如果包设定为 tom.com,则该类应该在 Classpath 可以存取到的路径下的 tom 目录下的 com 目录找到。没有设定包管理器的类会归为预设包(Default Package),编译后的类文件必须置于 Classpath 的路径中。
为了能建立与包相对应的文件结构,在编译时可以加入 -d 参数,并指定产生的类文件要存储在哪一个目录之下。
EX 9.4 PackageDemo.java
package tom.com;
public class JavaNotesChap0903_PackageDemo
{
public static void main(String[] args)
{
System.out.println("Hello, Package!");
}
}