1、第4讲 类,4.1 Java技术类 4.2 类的继承 4.3 接口 4.4 包,类是组成Java程序的基本元素,它封装了一系列的变量(即数据成员,也称为“域(field)”)和方法(即成员方法 method),是一类对象的原型。创建一个新的类,就是创建一个新的数据类型。实例化一个类,就得到一个对象。因此,对象就是一组变量和相关方法的集合,其中变量表明对象的状态、属性,方法表明对象所具有的行为。,4.1 Java技术类 4.1.1 类的定义,一、Java 类的基本语法: * class * 示例: public class MyFirstClass private int age;public
2、void setAge(int value) age = value; ,二、声明属性 属性的基本语法: * = ; 示例: public class MyFirstClass private int x;private float y = 10000.0F;private String name = “NIIT“; ,三、声明方法 方法的基本语法: * ( * ) * 示例: public class Dog private int weight;public int getWeight() return weight;public void setWeight(int newWeight)
3、 if ( newWeight 0 ) weight = newWeight; ,4.1.2 类对象 创建类的变量称为类的实例化,类的变量也称为类对象、类的实例等(区分类变量、实例变量和类的变量、类的实例)。 类的对象是在程序运行中创建生成的,其所占的空间在程序运行中动态分配。当一个类的对象完成了它的使命,为节省资源,Java的垃圾收集程序就会自动收回这个对象所占的空间。即类对象有自己的生命周期。 一、创建对象 创建类的对象需用new运算符,一般形式为:对象名 = new 类名() 或 对象名=new 类名(参数表)例如:rect1 = new Rect(); 为指定的类在内存中分配空间,并将
4、空间的引用给对象变量。 new运算符也可以与类声明一起使用来创建类的对象。 例如:Rect rect1 = new Rect();,二、访问对象成员 要访问对象成员(包括属性和方法),使用点号。. 示例: d.setWeight(42); d.weight = 42; / only permissible if weight is public,4.1.3 构建器 在Java中,任何变量在被使用前都必须先设置初值。Java提供了为类的成员变量赋初值的专门功能:构造方法(类成员变量可以直接在定义时赋值给定,如果没有给定也会有缺省值0,但是为体现封装性,一个类的内部细节要安全,所以最好不要随便修改
5、。)构造方法是一种特殊的成员方法,它的特殊性反映在如下几个方面: (1)构造方法名与类同名。 (2)构造方法无返回值,也没有返回类型。 (3)每一个类可以有零个或多个构造方法,可以重载。 (4)构造方法在创建对象时自动执行,一般不能显式地直接调用。,注意: 1、当方法形式参数名与成员变量名相同时,使用时会产生混淆,在Java语言中,可用this关键字表示本对象。 2、允许构造方法重载,允许一个构造方法调用另一个构造方法,调用的方法是:this(实际参数表)该语句根据参数表调用相应的构造方法。但此时,this调用构造器代码,必须是该方法的首行。 3、没有参数的构造方法叫做无参构造方法。一个类若没
6、有任何用户定义的构造方法,Java会自动提供一个无参的空构造方法,在创建对象时,使用这个无参的构造方法为类对象的成员变量赋数据类型的缺省值。一旦用户定义了自己的构造方法,Java就不再提供自动产生的无参构造方法。,构造方法重载的例。class RectOverloaddouble length;double width;double area() return length * width; RectOverload(double l, double w) length = l;width = w;RectOverload(double s),class RectDemo4 public st
7、atic void main(String args) RectOverload rect1 = new RectOverload(10,20);RectOverload rect2 = new RectOverload(6); double ar;ar = rect1.area(); System.out.println(“长方形的面积是: “ + ar);ar = rect2.area(); System.out.println(“正方形的面积是: “ + ar);,程序运行结果如下:长方形的面积是: 200.0正方形的面积是: 36.0,this(1,2);,length = s; wi
8、dth = s;,this(1,2);,length = s; width = s;,4.1.4 类和成员的修饰符 在类和类的成员定义时可以使用一些修饰符来对类和成员的使用作某些限定。一般将修饰符分为两类:访问控制符和非访问控制符。 访问控制符有public、protected、private等,它们的作用是给予对象一定的访问权限,实现类和类中成员的信息隐藏。 非访问控制符作用各不相同,有static、final、native、volatile、abstract等。某些修饰符只能应用于类的成员,某些修饰符既可应用于类也可应用于类的成员。,一、访问权限符: (1)public: 对于成员来说:任
9、何其他类都可以访问它们,不管在同一个包中还是在另外的包中。 对于类来说:也是一样。 (2)private: 对于成员来说:只能在该成员隶属于的类中访问。 对于类来说:类不可以声明为private。 (3)protected: 对于成员来说:相同包中的类可以访问(包访问权限);派生的子类也可以访问,即使不在同一个包内,与默认的区别就是多一个子类可以访问。 对于类来说:类不可以声明为protected 。,说明: (1)、每个编译单元(类文件)都仅能有一个public class。 (2)、public class的名称(包含大小写)必须和其类文件同名。 (3)、一个类文件(*.java)中可以不
10、存在public class。 (4)、class不可以显式是private和protected。 (5)、如果不希望某个class产生任何的对象,可以将该类得所有构造函数设置成private。但是即使这样也可以生成该类的对象,就是class的static的成员(属性和方法)可以办到 。,类的属性修饰符(Only four)。 1、public class XXXX public是,表示 这个类对于任何其他类可见。 2、final calss XXXXfinal是,表示这个类不能被任何类所继承(断子绝孙,String就是一个典型的final类)。 3、abstract class XXXXab
11、stract是,表示这个类是一个抽象类。 4、什么都不写 class XXXX , 表示这个类仅对于他所在的包(不包括子包)中的类可见 。,二、非访问控制符 1、static修饰符 使用static修饰符来修饰类的成员变量和方法成员,使它们成为静态成员,也称为类成员。静态成员存储于类的存储区,属于整个类,而不属于一个具体的类对象。因为静态成员属于整个类,所以它被所有该类对象共享。在不同的类对象中访问静态成员,访问的是同一个。 对静态成员的使用要注意两点: (1)static 块代码在类被加载时仅执行一次。 (2)静态方法不能访问属于某个对象的成员变量,而只能处理属于整个类的成员变量。即静态方法
12、只能处理静态成员变量。 (3)可以用两种方式调用静态成员,它们的作用相同。变量:类名.变量、类对象.变量。方法:类名.方法名()、类对象.方法名()。,程序运行结果如下:a = 42b = 99,静态成员的使用。class StaticDemo int a = 42;static int b = 99;static void callme() System.out.println(“a = “ + a);class StaticByName public static void main(String args) StaticDemo.callme(); System.out.println(
13、“b = “ + StaticDemo.b);,static,/错误,不能使用非静态字段,2、final修饰符 final修饰符可应用于类、方法和变量。final的意义为终极或最终。 final类不能被继承,即final类无子类。 final方法不能被覆盖,即子类的方法名不能与父类的final方法名相同。 final变量实际上是Java语言的符号常量,可在定义时赋初值或在定义后的其他地方赋初值,但不能再次赋值,习惯上使用大写的标识符表示final变量。例如:final double PI = 3.1416;final double G = 9.18; 因为final变量不能改变,没有必要在每个
14、对象中进行存储,一般将final变量声明为静态,以节省存储空间。例如: static final double PI = 3.1416;,3、abstract修饰符 abstract修饰符可应用于类和方法,称为抽象类和抽象方法。抽象类需要继承、抽象方法需要在子类中实现才有意义。 4、native修饰符 native修饰符一般用来声明用其他语言如C、C+、FORTRAN、汇编等书写方法体并具体实现方法功能的特殊方法。由于native方法的方法体使用其他语言编写。所以所有的native方法都没有方法体。native方法可应用于实时性强、执行效率高,运行速度要求较高的场合。 5、synchroniz
15、ed修饰符 synchronized修饰符可应用于方法或块,在多线程 程序中,对用于共享的方法和块加互斥锁,使得任一时刻,synchronized方法或块只能由一个线程执行或操作。,枚举的类型,4.1.5 枚举类型 enum 类型字段由一组固定的常量组成。 可使用 enum 关键字来定义 enum 类型。例如,指定一周每一天的 enum 类型: public enum Day SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY,SATURDAY enum 类主体可包括方法和其他字段。 编译器当创建 enum 时自动添加一些特殊的方法。 所有
16、 enum从 java.lang.Enum 显示扩展。因为 Java 不支持多重继承,enum 不能扩展为任何别的内容。,pacekage cards.tests; import cards.domain.PlayingCard; import cards.domain.Suit; public class TestPlayingCardpublic static void main(String args)PlayingCard card1=new PlayingCard(Suit.SPADES,2);System.out.println(“card1 is the“ +card1.getR
17、ank()+“of“+card1.getSuitName(); ,package card.domain; public enum SuitSPADES,HEARTS,CLUBS,DIAMONDS ,package cards.domain; public class PlayingCardprivate Suit suit;private int rank;public PlayingCard(Suit suit,int rank) this.suit=suit; this.rank=rank; public Suit getSuit() return suit; public String
18、 getSuitName()String name=“;switch(suit)case SPADES:name=“Spades“;break;case HEARTS:name=“Hearts“;break;case CLUBS:name=“Clubs“; break;case DIMAONDS:name=“Dimaonds“;break;default:return name; ,4.1.6 类的使用 一、私有成员的访问 为了降低类间的耦合性,可以为类成员指定private修饰符,表示该成员只能在该类内部访问。若需要在其他类中访问私有成员,只能通过取数和送数的方法来访问。这样的方法常命名为g
19、etXxx()和setXxx()等。,私有成员的访问。class RectangleRC private double length;private double width;double getLength() return length; double getWidth() return width; RectangleRC(double l, double w) length = l; width = w; ,class RectDemo5 public static void main(String args) RectangleRC rect1 = new RectangleRC(8
20、,7);double ar = rect1.getLength()*rect1.getWidth();System.out.println(“长方形的面积是: ”+ ar); ,二、方法参数是类的对象 方法的参数类型除了基本类型外,还可以是引用类型。应用引用类型的方法参数,可在方法间传送数据。 因为在类的对象中实际存储为对象的引用,因此在调用类参数时方法间传送的是引用。因此,若在被调方法中修改了引用类型形式参数的取值,则调用方法对应的实际参数也将发生相应的变化。即调用方法与被调方法之间是“引用单向传送,数据双向传送”。,引用类型的方法参数是方法间传送数据的桥梁。 class RefParame
21、terdouble width,length,area;RefParameter(double w,double l) width = w; length = l; void calArea( RefParameter r ) r.area = r.width * r.length; ,程序运行结果如下: 长方形面积为 :200.0,class PassObjectpublic static void main(String args)RefParameter rr = new RefParameter(10,20);rr.calArea(rr);System.out.println(“长方形
22、面积为 :“ + rr.area);,三、方法返回值为类的对象 在Java语言中,方法的返回值类型也可以为引用类型,如:类。 方法的返回值类型为引用类型。,运行结果:长方形面积为 :200.0,class RetClassdouble width,length,area;RetClass(double w,double l) width = w; length = l; RetClass calArea(RetClass r) r.area = r.width * r.length; return r; class ReturnObjectpublic static void main(Str
23、ing args)RetClass rr = new RetClass(10,20);rr = rr.calArea(rr);System.out.println(“长方形面积为 :“ + rr.area); ,四、类对象作为类的成员 类的数据成员也可以是引用类型的数据,如数组、字符串和类等。若一个类的对象是一个类的成员时,要用new运算符为这个对象分配存储空间。在包含类数据成员的类及类的实例中可以访问类数据成员的成员。 类对象作为类的成员。,class RectCdouble width,length;RectC(double w,double l) width = w; length =
24、l; class RectangleC / 具有两个成员的类RectC r = new RectC(10,20); / 对象成员是需要初始化的double area; / 基本类型成员 class ClassMemberpublic static void main(String args)RectangleC rr = new RectangleC();rr.area = rr.r.width * rr.r.length;System.out.println(“长方形面积为 :“ + rr.area); ,程序运行结果如下: 长方形面积为 :200.0,五、内部类(Inner class)
25、内部类(放在内部的类),也称为嵌套类。允许一个类的定义被放到另一个类定义里、一个语句块里或一个表达式内部。内部类是一个有用的特征,因为它们允许将逻辑上同属性的类组合到一起,并在另一个类中控制一个类的可视性。示例:在一个类中定义类(内部类)。,程序运行结果如下: 第一个长方形面积是: 200.0 第二个长方形面积是: 18.0,class RectDemo6 public static void main(String args) double ar;class RectangleR double length, width;double area() return length * width
26、; / 返回面积 void setDim(double w, double l) width = w; length = l; RectangleR rect1 = new RectangleR(), rect2 = new RectangleR();rect1.setDim(10, 20); rect2.setDim(3, 6); /初始化对象ar = rect1.area(); System.out.println(“第一个长方形面积是: “ + ar);ar = rect2.area(); System.out.println(“第二个长方形面积是: “ + ar); ,内部类的名称不能
27、与所嵌套的类相同,而且只能在定义的范围中使用。内部类具有下面一些特性: (1)内部类可以被定义在方法中。它可以访问嵌套类的方法的final变量。 (2)内部类可以使用所嵌套类的类变量和实例变量以及所嵌套的块中的本地变量。 (3)内部类可以被定义为abstract抽象类。 (4)内部类可以被声明为private或protected,以便防护它们不受来自外部类的访问。访问保护不阻止内部类使用其他类的任何成员。 (5)一个内部类可以作为一个接口,由另一个内部类实现。 (6)声明为static的内部类成为顶层类。这些内部类失去了在本地范围和其他内部类中使用数据或变量的能力。 (7)内部类不能声明任何s
28、tatic成员,只有顶层类可以声明static成员。因此,一个需求static成员的内部类必须使用来自顶层类的成员。,4.2 类的继承(inheritance),继承是面向对象程序设计的另一个重要特色,类继承也称为类派生,是指一个类可以继承其他类的非私有成员,实现代码复用。被继承的类称为父类或超类,父类包括所有直接或间接被继承的类;继承父类或超类后产生的类称为派生类或子类。 Java语言以Object类作为所有类的父类,所有的类都是直接或间接地继承Object类得到的。Java还提供不同层次的标准类,使用户可根据需要派生自己的类。 在Java语言中,只允许单继承。 类继承不改变成员的访问权限,
29、父类中的成员为公有的或被保护的,则其子类的成员访问权限也继承为公有的或被保护的。,4.2.1 类继承的实现 Java中的继承是通过extends关键字来实现的,在定义新类时使用extends关键字指明新类的父类,就在两个类之间建立了继承关系。 1、定义子类 例如:public class HelloApplet extends Appletclass MyException extends Exception 一般地,在类声明中,加入extends子句来创建一个类的子类。若无extends子句,则该类为java.lang.Object的子类。,2、子类的初始化 子类必须调用父类的构造方法对继承
30、的变量初始化。父类构造方法的调用遵循如下的原则: (1)若父类是无参数的构造方法,则子类一般缺省调用该构造方法,当然也可以显式用super来调用,格式为:super()。 (2)若子类无自己的构造方法,则它将调用父类的无参构造方法作为自己的构造方法;(若父类没有无参构造方法,出错。)若子类有自己的构造方法,则在创建子类对象时,它将先调用父类的无参构造方法,然后再执行自己的构造方法。 (3)若父类是有参数的构造方法,子类可以通过在自己的构造方法中使用super关键字来调用它,但这个调用语句必须是子类构造方法的第一个可执行语句。 3、类继承的传递性 类继承具有传递性,即子类只能继承父类的所有非私有
31、成员,也继承父类的父类直至祖先所有的所有非私有成员。,继承例5.6中的类RectConstructor时对父类的成员变量赋初值。,子类继承了父类的变量和方法,代码复用使得程序简洁高效。 程序运行结果如下:长方体体积 = 210.0,class Cube extends RectConstructordouble height;Cube(double l,double w,double h) super(l,w); height = h; void vol() System.out.println(“长方体体积 = “+ area() * height); public class CubeDe
32、mo public static void main(String args) Cube c = new Cube(7,6,5); c.vol(); ,4、成员变量的隐藏和方法成员的覆盖 在类的继承中,子类可以定义新成员,也可以重定义继承的成员。 在子类中重定义继承的成员的目的是修改父类的属性和行为,此时,在子类中,通过成员名称仅能直接访问本身新增的成员,若有必要访问继承的成员,可用关键字super。 (1)成员变量的隐藏 若子类重定义了继承的变量,则继承的变量被隐藏起来,直接使用的是子类重定义的变量,但继承的变量仍占据空间,可通过super或父类名来访问。,在子类中定义了与父类同名的变量,从
33、而隐藏了父类成员变量,这种隐藏变量可加super前缀来访问。,程序运行结果如下:Subclass : 200Superclass : 100,super不能用于静态方法中。因为静态方法只能访问静态变量,在静态方法中,父类的静态变量可通过类名前缀来引用。,class Aint x = 100; /成员变量可以直接赋值,若没有缺省0。/但一般情况下采用构造函数来实现成员变量的初始化。 class B extends Aint x = 200; / 在子类中定义与父类同名变量xvoid print()System.out.println(“Subclass : “ + x); / 直接输出为子类变量
34、System.out.println(“Superclass : “ + super.x); / 父类变量用super访问public static void main(String args) (new B().print(); ,(2)成员方法覆盖 在子类中也可以重新定义继承的方法,这称为成员方法的覆盖。 方法的覆盖中需注意的是:子类在重新定义父类已有的方法时,应保持与父类完全相同的方法头声明,即应与父类有完全相同的方法名、返回值和参数列表。否则就不是方法的覆盖。而是在子类定义自己的与父类无关的成员方法,父类的方法未被覆盖,所以仍然存在。 下述规则适用于覆盖方法: 覆盖方法的返回类型必须与
35、它所覆盖的方法相同。 覆盖方法不能比它所覆盖的方法访问性差。 覆盖方法不能比它所覆盖的方法抛出更多的异常。,Object 类,4.2.2 Object类 Object 类是 Java 中的所有类的根。 没有 extends 子句的类声明暗含 extendsObject。例如: public class Employee . 等同于: public class Employee extends Object . object 类的两个重要方法: equals() toString(),equals 方法,1、equals()方法= 操作符确定是否两个引用彼此是相等的(即引用相同的对象)。equa
36、ls() 方法确定是否对象是相同的但不是必须同一的。.equals() 方法的对象实现使用 = 操作符。 用户类可覆盖 equals 方法来实现特定域的等同性测试。注:如果覆盖了 equals 方法,应覆盖 hashCode 方法。 2、toString() toString() 方法具有以下特征: 此方法将对象转换为 String。 在字符串拼接中使用此方法。 覆盖此方法来提供关于使用可读格式用户定义对象的信息。 使用 wrapper 类的 toString() 静态方法将原始类型转换为字符串。,4.2.3 抽象类和抽象方法 abstract修饰的抽象类需要子类继承,在派生类中实现抽象类中的
37、抽象方法。抽象类被派生、抽象方法被子类实现后,才有实际意义。抽象方法是只有返回值类型、方法名、方法参数而不定义方法体的一种方法。抽象方法的方法体在子类中才编写实现。注意不能用abstract修饰构造方法、静态方法和私有(private)方法,也不能覆盖父类中的抽象方法。 抽象方法必须定义在抽象类中。抽象类是一种未实现的类,抽象类不能用new实例化一个对象。 【例5.16】计算底面半径为2高为3的圆柱体体积和长、宽、高分别为3、2、4的长方形体积。,程序的运行结果如下: 圆柱体体积 = 37.6992 长方体体积 = 24.0,abstract class Shape / 定义抽象类Shaped
38、ouble radius,length,width,height; abstract double vol(); / 抽象方法vol Shape(double r,double h) /定义构造方法radius = r; height = h; Shape(double l,double w,double h) length = l; width = w; height = h; class Circle extends ShapeCircle(double r,double h) super(r,h); double vol() /实现抽象方法 return(3.1416 * radius
39、* radius * height); class Rectangle extends Shape Rectangle(double l,double w,double h) super(l,w,h); double vol() return(length * width * height); ,class AbstractClassDemo public static void main(String args) Circle c = new Circle(2,3);Rectangle r = new Rectangle(3,2,4);System.out.println(“圆柱体体积 =
40、” + c.vol();System.out.println(“长方体体积 = ”+ r.vol(); ,4.2.4 类对象之间的类型转换 有继承关系的父类对象和子类对象之间也可以在一定条件下相互转换。父类对象和子类对象的转换需要注意以下原则: (1)子类对象可以被视为是其父类的一个对象,反之则不可。 (2)若一个方法的形式参数定义的是父类的对象,则调用该方法的实际参数可以使用子类对象。 (3)若父类对象引用指向的实际是一个子类对象,则这个父类对象的引用可以用强制类型转换转化成子类对象的引用。,4.3 接口(interface),接口是若干完成某一特定功能的没有方法体的方法(抽象方法)和常量的
41、集合。接口仅提供了方法协议的封装。为了获取接口功能和真正实现接口功能需要使用类来继承该接口。在继承接口的类中,通过定义接口中抽象方法的方法体(即抽象方法的覆盖)来实现接口功能。 Java语言使用接口来实现类间多重继承的功能,从而弥补了Java语言只支持类间单重继承,描述复杂实际问题处理不方便的不足。,4.3.1 接口的定义和实现 1、接口的定义 接口有类似类的结构,其定义格式如下:修饰符 interface 接口名 extends 父接口名表/ 接口体 接口体中:所有成员变量必须赋初值,一旦赋值以后无法修改 接口定义包括定义接口名和接口体。接口名是一合法的标识符。接口体同抽象类相似,为变量和抽
42、象方法的集合,但没有构造方法和静态方法。接口体中定义的变量均为终极(final)的、静态(static)的和公共(public)的。接口体中定义的方法均为抽象的和公共的。由于接口所有成员均具有这些特性,相关的修饰符可以省略。,2、接口的实现 在某个继承接口的派生类中为接口中的抽象方法书写语句并定义实在的方法体称为实现这个接口。派生类实现哪个或哪些接口用implements说明,不能用extends说明。 派生类在实现接口时,还要注意:若实现接口的类不是抽象类(即派生类不是抽象类),则在该类的定义部分必须实现指定接口的所有抽象方法。方法体可以由java语言书写,也可以由其他语言书写。因为是覆盖方
43、式,所以方法头部分应该与接口中的定义完全一致,即有完全相同的参数表和返回值。,程序运行结果如下: 边长分别为3和4的长方形面积为:12.0,接口的实现。 interface Irectdouble w=3,l=4; void compute(); class Crect implements Irectpublic void compute()System.out.println(“边长分别为3和4的长方形面积为:“+w*l); public class InterfaceDemopublic static void main(String args)Crect r = new Crect()
44、;pute(); ,4.3.2 接口的继承和组合 接口也可以通过关键字extends继承其他接口。子接口将继承父接口中所有的常量和抽象方法。此时,子接口的非抽象派生类不仅需实现子接口的抽象方法,而且需实现继承来的抽象方法。所有继承过来的方法都必须实现,不允许存在未被实现的接口方法。示例:接口的继承。interface AString a = “在接口A中“;void showA();,程序运行结果如下: 在接口A中 在接口B中 在接口C中,4.3.3 接口的多态 接口的使用使得方法的描述说明和方法功能的实现分开考虑,这有助于降低程序的复杂性,使程序设计灵活,便于扩充修改。这也是Java面向对象
45、程序设计方法中多态特性的体现。示例:定义接口并实现接口,说明接口的多态。,interface OneToN int disp(int n); class Sum implements OneToNpublic int disp(int n) for(int s = 0,i = 1;i = n;i +) s += i;return s; class Pro implements OneToN public int disp(int n) for(int m=1,i = 1;i = n;i +) m *= i;return m; ,public class UseInterfacepublic s
46、tatic void main(String args)int n = 10;Sum s = new Sum();Pro p = new Pro();System.out.println(“1至n的和 = ” + s.disp(n);System.out.println(“1至n的积 = ” + p.disp(n); ,程序的运行结果如下: 1至n的和 = 55 1至n的积 = 3628800,4.3.4 接口类型的使用 接口可以作为一种引用类型来使用。任何实现接口的类的对象都可以存储在该接口类型的变量中。通过这些变量可以访问类所实现的接口中的方法。Java运行时系统动态地确定应该使用哪个类中
47、的方法。,示例:接口类型的使用(用上例接口)。public class UseInterface1public static void main(String args)int n = 10; OneToN otn; Sum s = new Sum(); otn = s;System.out.println(“1至n的和 = “ + otn.disp(n);Pro p = new Pro(); otn = p;System.out.println(“1至n的积 = “ + otn.disp(n);,4.4 包(package),一组相关的类和接口集合称为包。包体现了Java语言面向对象特性中的
48、封装机制,包将java语言的类和接口有机地组织成层次结构,这个层次结构与具体的文件系统的目录树结构层次一致。因此,Java包就是具有一定相关性在文件系统中可准确定位的Java文件的集合。,4.4.1 创建包 包由包语句package创建,其语法格式如下:package 包名1.包名2. 关键字package后是不同层次的包名,各级包名之间用“.”号分隔。通常情况下,包名称的元素被整个地小写。 在Java程序中,package语句必须是程序的第一条非空格、非注释语句。通过package语句,可将Java程序分层次地存放在不同的目录下,目录名称与包的名称相同。 如在Rect类定义前加语句package创建包: package ch05; 1/编译程序完成生成Rect.class文件后,可将当前目录的Rect.class文件复制或移动到创建的ch05子目录中。若在编译上述程序时,带d编译参数来进行编译,即使用编译命令: javac -d 目录名 Rect.java来进行编译,java系统自动在命令行中d参数指定的目录(该目录已经存在)中创建ch05(与程序中的包名相同)子目录,然后自动将生成的类文件Rect.class存放其中。如:javac d d:temp Rect.java,