第 6章 Java中类, 对象, 接口及包的概念
第 6章 Java中类、对象、接口及
包的概念
6.1 类的基本概念
6.2 对象
6.3 类的继承概念
6.4 Java中接口与包的概念
第 6章 Java中类, 对象, 接口及包的概念
6.1 类的基本概念
传统的过程式语言, 如 C,由于它的设计方式与客
观世界之间存在差距, 使得程序的编写首先必须定义
所要实现的功能, 然后确定需采取的步骤, 即所谓的
,逐步求精, 的结构程序设计方法 。 实际开发中, 当
程序大到一定程度的时候, 其调试和维护就变得很困
难, 使用过程式语言就会感到力不从心了 。
第 6章 Java中类, 对象, 接口及包的概念
前面我们说过, Java是一种纯面向对象的编程语
言, 而面向对象程序设计是近些年来才发展起来的程
序设计方法, 其基本思想是将现实世界中的事物抽象
为对象, 抽象出来的对象被赋给相应的状态和行为,
通过对消息的响应完成一定的任务 。 在现实生活中,
任何事物都可以被认为是对象 (Object),如:
① 电梯
② 街头的自动售货机
③ 街上跑的汽车
④ 凳子
⑤ 人
……
第 6章 Java中类, 对象, 接口及包的概念
上面列举的对象都有两个共性:
(1) 具有一定的状态和特性 。 比如汽车有轮胎, 发
动机, 方向盘等 。
(2) 每个对象对应一组特定的操作 。 比如汽车需保
养, 加油, 清洗等 。
面向对象程序设计方法就是把现实世界中对象的
状态和操作抽象为程序设计语言中的对象,达到二者
的统一。同一种对象的所有共性进行抽象,又得到了
类的概念。
第 6章 Java中类, 对象, 接口及包的概念
所以, 面向对象程序设计中的对象是由描述状态
的变量和对这些变量进行维护和操作的一系列方法组
成的事务处理单位, 而类相当于创建对象实例的模板,
通过对其实例化得到同一类的不同实例 。 本章我们将
讨论类的特性, 成员变量, 方法, 对象的建立及初始
化, 对象的继承及接口与包等内容 。
第 6章 Java中类, 对象, 接口及包的概念
类是对一个或几个相似对象的描述, 它把不同对
象具有的共性抽象出来, 定义某类对象共有的变量和
方法, 从而使程序员实现代码的复用, 所以说, 类是
同一类对象的原型 。 创建一个类, 相当于构造一个新
的数据类型, 而实例化一个类就得到一个对象 。 Java
为我们提供了大量的类库, 如果从已知类库入手来构
造自己的程序, 不仅能有效地简化程序设计, 而且能
很好地学习面向对象程序设计方法 。
其实, 前面很多例子已经对类的组成有了明确地
说明, 一个类的实现包含两部分内容:声明和实体 。
类的各部分组成如图 6.1所示 。
第 6章 Java中类, 对象, 接口及包的概念
图 6.1
p u b l i c c l a s s s t a c k
{
p r i v a t e V e c t o r i t e m s ;
p u b l i c S t a c k ( ) {
i t e m s = n e w V e c t o r ( 1 0 ) ;
}
p u b l i c O b j e c t p u c h ( O b j e c t i t e m ) {
i t e m s, a d d E l e m e n t ( i t e m ) ;
r e t u r n i t e m ;
}
p u b l i c s y n c h r o n i z e d O b j e c t p o p ( ) {
i n t l e n = i t e m s, s i z e ( ) ;
O b j e c t o b j = n u l l ;
i f ( l e n = = 0 )
t h r o w n e w E m p t y S t a c k E x c e p t i o n ( ) ;
o b j = i t e m s, E l e m e n t A t ( l e n - 1 ) ;
i t e m s, r e m o v e E l e m e n t A t ( l e n - 1 ) ;
r e t u r n o b j ;
}
p u b l i c b o o l e a n i s E m p t y ( ) {
i f ( i t e m s, s i z e ( ) = = 0 )
r e t u r n t r u e ;
e l s e
r e t u r n f a l s e ;
}
}
类的实体
类的声明
变量定义
构造函数
方法定义
第 6章 Java中类, 对象, 接口及包的概念
6.1.1 类的声明
类声明包括关键字 class,类名及类的属性 。 类名
必须是合法的标识符, 类的属性为一些可选的关键字 。
其声明格式如下:
[public|private|friendly|protected] [abstract][final] class
className
[extends superclassName][implements interfaceNameList]
{...}
其中,第一项属于访问控制符,它不仅针对于类,
类的变量、方法的访问也有该项的限制,我们后面会
做专门的介绍。其他的修饰符说明如下:
第 6章 Java中类, 对象, 接口及包的概念
● abstract:声明该类不能被实例化 。
● final:声明该类不能被继承, 即没有子类 。
● class class Name:关键字 class告诉编译器表示类的声
明以及类名是 class Name。
● extends super class Name,extends 语句扩展 super class
Name为该类的父类。
第 6章 Java中类, 对象, 接口及包的概念
● implements interface Name List:声明类可实现
一个或多个接口, 可以使用关键字 implements并且在其
后面给出由类实现的多个接口名字列表, 各接口之间
以逗号分隔 。 如图 6.1中的
public class stack
{...}
即为类的声明 。
第 6章 Java中类, 对象, 接口及包的概念
6.1.2 类的实体
类体是类的主要部分, 包括变量的说明及该类所
支持的方法, 我们习惯称之为成员变量和成员方法 。
需要注意的是, 除了类体中定义的变量与方法外, 该
类还继承了其父类的变量与方法 。 当然, 对父类变量
和方法的访问要受到访问控制条件的限制 。 类体说明
的格式为
class class Name {
variable Declaration
method Declaration
}
第 6章 Java中类, 对象, 接口及包的概念
读者可参照图 6.1仔细体会类体所包含的内容 。
1,变量
Java中变量的说明可以分为两种:类成员变量的说
明和方法变量的说明 。 其变量声明格式为
[public|protected|private] [static][final] [transient][volatile]
type variable Name
上述声明格式中, 第一项指的是访问控制格式 (我
们后面会有介绍 ),另外的几项我们说明如下:
第 6章 Java中类, 对象, 接口及包的概念
● static,成员控制修饰符, 说明该类型的变量为静
态变量, 或者称之为类变量 。 说明静态变量类型后则
该类的所有实例对象都可以对其共享, 而且访问静态
变量无须事先初始化它所在的类 。
● final:常量声明修饰符, 与 C/C++类似, 用该符
号声明后, 在程序的运行过程中不能再改变它的值 。
实际使用中, final往往与 static结合在一起使用 。 比如:
final int INDEX = 1000;
static final int LOOP=10;
第 6章 Java中类, 对象, 接口及包的概念
● volatile:异步控制修饰符, 表示多个并发线程
共享的变量, 这使得各线程对该变量的访问保持一致 。
● transient:存储控制临时变量修饰符, 因为在
缺省的情况下, 类中所有变量都是对象永久状态的一
部分, 将对象存档时, 必须同时保存这些变量 。 用该
限定词修饰的变量指示 Java虚拟机:该变量并不属于
对象的永久状态 。 它主要用于实现不同对象的存档功
能 。
总之, 从变量定义的不同位置及所使用的限定词
不同来看, 变量可以分为三类:实例变量, 局部变量
和静态变量 。
第 6章 Java中类, 对象, 接口及包的概念
如果在类的方法代码段之外声明且没有限定词
static,则为实例变量 。 从它的定义我们可以看出, 实
例变量与类紧密相关, 如果一个类有多个实例对象,
那么每个实例对象都有自己的实例变量拷贝, 之间并
不影响 。
第 6章 Java中类, 对象, 接口及包的概念
如果在类的方法本体之中声明, 则为局部变量,
这有点与 C语言函数中定义的局部变量相似 。 由于局部
变量是在方法体内所定义, 因而只能在本方法中使用,
无所谓访问控制, 也不能用 static修饰符加以说明 。 另
外, 需要注意的是局部变量使用前必须初始化, 这也
是它与实例变量及后面要介绍的静态变量之间的不同
之处 。 局部变量可以与实例变量同名而相互不影响 。
如果将一个实例变量声明为 static,则为静态变量,
或称之为类变量 。 静态变量在类声明后就可以直接引
用, 但实例变量则不能, 必须在实例化对象后才可以
使用 。
第 6章 Java中类, 对象, 接口及包的概念
下面我们对实例变量与类变量加以详细地说明,
以加深读者的理解 。 比如我们可以如下来声明一个成
员变量:
class My Class {
public float variable1;
public static int variable2
}
第 6章 Java中类, 对象, 接口及包的概念
该例中声明了一个实例变量 variable1和一个类变
量 variable2。 今后当我们创建类的实例的时候, 系统就
会为该实例创建一个类实例的副本, 但系统为每个类
分配类变量仅仅只有一次, 而不管类创建的实例有多
少 。 当第一次调用类的时候, 系统为类变量分配内存 。
所有的实例共享了类的类变量的相同副本 。 在程序中
可通过一个实例或者类本身来访问类变量 。 例如:
…
My Class A=new My Class();
My Class B=new My Class();
第 6章 Java中类, 对象, 接口及包的概念
A.variable1=100;
A.variable2=200;
B.variable1=300;
B.variable2=400;
System.out.println("A.variable1= "+A.variable1);
System.out.println("A.variable2= "+A.variable2);
System.out.println("A.variable1= "+A.variable1);
System.out.println("A.variable1= "+A.variable1);
...
第 6章 Java中类, 对象, 接口及包的概念
当我们从类实例化新对象的时候, 就得到了类实例
变量的一个新副本 。 这些副本跟新对象是联系在一起的 。
因此, 每实例化一个新 MyClass对象的时候, 就得到了
一个和 MyClass对象有联系的 variable1的新副本 。 当一个
成员变量用关键字 static被指定为类变量后, 其第一次调
用的时候, 系统就会为它创建一个副本, 之后, 类的所
有实例均共享了该类变量的相同副本 。 所以上述程序段
的输出结果为
A.variable1= 100
A.variable2= 400
B.variable1= 300
B.variable2= 400
第 6章 Java中类, 对象, 接口及包的概念
2,方法
Java程序通过方法完成对类和对象属性的操作。方法
定义了在类成员变量上的一系列操作,它只能在类的内
部声明并加以实现,其他的对象通过调用对象的方法得
到该对象的服务。方法的定义包含两部分内容:方法声
明和方法体。
1) 方法声明
方法声明的一般格式如下:
[public/protected/private][static][final][abstract]
[native][synchronized]
return Type method Name([param List]) [throws
exceptionList]
{...}
第 6章 Java中类, 对象, 接口及包的概念
在方法声明中应包括方法名, 方法的返回值类型,
方法的修饰词, 参数的数目和类型及方法可能产生的
例外 。 从其声明格式中可以发现, 不一定要全部显示
并指明所有的信息, 方法最基本的声明格式为
return Type method Name()
{...}
一般声明格式中的第一项是访问控制属性, 后面
会介绍 。 其他几个修饰词我们说明如下:
第 6章 Java中类, 对象, 接口及包的概念
● static,说明该方法为静态方法。与变量的定义
类似,静态方法我们也称作类方法,与之对应,其他
的方法就为实例方法。静态方法属于类,所以只要对
类作了声明,就可以调用该类的类方法,即使用时无
须类的初始化。当然,实例方法只能在类的实例或子
类的实例中调用。类方法只能操作类变量而不能访问
定义在类中的实例变量,这是实际使用过程中经常出
错的地方。例如:
第 6章 Java中类, 对象, 接口及包的概念
class A {
int x;
static public int x() {
return x;}
static public void setX(int newX) {
x = newX;}
}
...
A myX = new A ();
A anotherX = new A ();
第 6章 Java中类, 对象, 接口及包的概念
myX.setX(1);
anotherX.x = 2;
System.out.println("myX.x = " + myX.x());
System.out.println("anotherX.x = " + anotherX.x());
...
当我们编译的时候, 编译器会给出以下的错误信息:
A.java:4,Can't make a static reference to
nonstatic variable x in class A.
return x;
第 6章 Java中类, 对象, 接口及包的概念
^
出现这个错误的原因是类方法不能访问实例变量, 如果
把类的定义改为
class AnIntegerNamedX {
static int x;
static public int x() {
return x;}
static public void setX(int newX) {
x = newX;}
}
第 6章 Java中类, 对象, 接口及包的概念
类就可以成功编译了:
myX.x = 2
anotherX.x = 2
实例成员和类成员之间的另外不同点是类成员可以在类
本身中访问, 而不必实例化一个类来访问类成员 。
第 6章 Java中类, 对象, 接口及包的概念
下面再对上面的代码进行修改:
...
A.setX(1);
System.out.println("A.x = " + A.x());
...
这里我们不用实例化类对象 myX和 anotherX就可以
直接从类 A中设置 x并输出 x。 这样同样可以得到类变量
x的值 。
第 6章 Java中类, 对象, 接口及包的概念
● abstract,说明一个方法是抽象方法, 即该方法
只有方法说明而没有方法体 。 抽象方法的实现须由该
方法所在类的子类来实现 。 如果一个类包含一个或多
个抽象方法, 则该类必须为抽象类 。 抽象类不能被实
例化 。 例如:
class Shape{
abstract void draw();}
该例中的说明方法 draw()为抽象方法 。
第 6章 Java中类, 对象, 接口及包的概念
● final,final方法类似于常量的定义,它说明一
个方法为终极方法,即它不能被子类重载。说明为
final的方法往往与关键字 private一起使用,避免出错。
例如:
...
private final meth_final()
{...}
第 6章 Java中类, 对象, 接口及包的概念
● native,synchronized:程序中 native指明本方
法是用与平台有关的开发语言编写的,也就是说用来
把 Java代码和其他语言的代码集成在一起。
synchronized主要用于多线程程序设计,说明某一方法
是同步方法,用来控制多个并发线程对共享数据的访
问。我们后面在讲线程的时候还要作介绍。
第 6章 Java中类, 对象, 接口及包的概念
2) 方法重载
Java中方法的重载指的是多个方法共用一个名字
(这样可实现对象的多态 ),同时, 不同的方法要么参数
个数各不相同, 或者是参数类型不同 。 Java提供的标
准类中包含了许多构造函数, 并且每个构造函数允许
调用者为新对象的不同实例变量提供不同的初始数值 。
比如, java.awt.Rectangle就有三个构造函数:
Rectangle(){};
Rectangle(int width,int height){};
Rectangle(int x,int y,int width,int height){};
当我们传递不同的参数时, 构造出来的对象的实
例具有不同的属性 。
第 6章 Java中类, 对象, 接口及包的概念
3) 方法中参数的使用
在方法的声明格式中, 需要指明返回值的类型 。
当一个方法不需要返回值的时候, 其类型说明为 void,
否则方法体中必须包含 return语句 。 返回值既可以是基
本数据类型, 也可以是复杂数据类型 。
在 C语言, PASCAL语言中, 函数, 过程的参数都
存在值传递 /参数传递的问题 。 比如 C语言中如果参数
是指针或数组名则为参数传递 。 我们知道, Java中由
于取消了指针, 不可能像 C一样直接操作内存, 但是由
于对象的动态联编性, 复杂数据类型作参数相当于指
针的使用, 即参数传递, 而基本数据类型作参数传递
则相当于值传递 。 比如下例:
第 6章 Java中类, 对象, 接口及包的概念
例 6.1
class swapByValue {
int x,y;
public swapByValue (int x,int y)
{ this.x=x;
this.y=y; }
public void swap(int x,int y)
{ int z;
z=x; x=y; y=z;}
public static void main(String args[]) {
第 6章 Java中类, 对象, 接口及包的概念
swapByValue s= new swapByValue (3,4);
Transcript.println("Before swap,x= "+s.x+" y= "+s.y);
s.swap(s.x,s.y);
Transcript.println("After swap,x= "+s.x+" y= "+s.y);}
}
运行结果如图 6.2所示 。
第 6章 Java中类, 对象, 接口及包的概念
图 6.2
第 6章 Java中类, 对象, 接口及包的概念
例 6.2
class swapByAddress {
int x,y;
public swapByAddress (int x,int y)
{ this.x=x;
this.y=y; }
public void swap(Integer x,Integer y)
{ Integer z;
z=x; x=y; y=z;
this.x=x.intValue();
this.y=y.intValue(); }
第 6章 Java中类, 对象, 接口及包的概念
public static void main(String args[]) {
swapByAddress s= new swapByAddress (3,4);
Transcript.println("Before swap,x= "+s.x+" y= "+s.y);
s.swap(new Integer(s.x),new Integer(s.y));
Transcript.println("After swap,x= "+s.x+" y= "+s.y);
} }
运行后的结果如图 6.3所示 。
第 6章 Java中类, 对象, 接口及包的概念
图 6.3
第 6章 Java中类, 对象, 接口及包的概念
在例 6.1和例 6.2中均出现了一个关键字 this,它起
什么作用呢? Java中关键字 this表示当前对象 。 因为实
际程序编写过程中, 可能会出现局部变量名和成员变
量名同名, 如例 6.3中有:
class swap By Address {
int x,y;
public swap By Address (int x,int y)
{ this.x=x;
this.y=y; }
第 6章 Java中类, 对象, 接口及包的概念
其中, 对象 swapByAdress中定义了两个成员变量 x、
y,同时方法 swapByAddress中也出现了以 x,y命名的
局部变量, 为了避免由此可能造成的二义性, 程序中
我们用 this关键字作前缀修饰词来指明是当前对象的实
例变量 。 与此类似, 用 this关键字同样可以调用当前对
象的某个方法 。
第 6章 Java中类, 对象, 接口及包的概念
4) 构造方法
构造方法用来初始化新创建的对象 。 类可以包含
一个或者多个构造方法, 不同的构造方法根据参数的
不同来决定要初始化的新对象的状态 。 所有的 Java类
都有构造方法, 它用来对新的对象进行初始化 。 构造
方法与类的名字是相同的 。 比如, Stack类的构造方法
的名字为 Stack,而 Rectangle类的构造方法的名字为
Rectangle,Thread类的构造方法的名字为 Thread。 下面
给出 Stack类的构造方法:
第 6章 Java中类, 对象, 接口及包的概念
public Stack() {
items = new Vector(10); }
Java支持对构造方法的重载, 这样一个类就可以
有多个构造方法, 所有的构造方法的名字都是相同的,
只是所带参数的个数和类型相异而已 。 下面是类 Stack
的另一个构造方法 。 这个构造方法是根据它的参数来
初始化堆栈的大小 。
public Stack(int initial Size) {
items = new Vector(initial Size); }
第 6章 Java中类, 对象, 接口及包的概念
从上面可以看出, 两个构造方法都有相同的名字,
但是它们有不同的参数列表 。 编译器会根据参数列表
的数目以及类型来区分这些构造方法 。 所以, 当创建
对象的时候, 要根据它的参数是否与初始化的新对象
相匹配来选择构造方法 。 根据传递给构造方法参数的
数目和类型, 编译器可以决定要使用哪个构造方法 。
如对于下面的代码, 编译器就可以知道应该是使用单
一的整型参数来初始化对象:
new Stack(10);
第 6章 Java中类, 对象, 接口及包的概念
与此相同, 当我们给出下面代码的时候, 编译器
选择没有参数的构造方法或者缺省的构造方法进行初
始化:
new Stack();
另外,如果生成的类不为它提供构造方法,系统
会自动提供缺省的构造方法。这个缺省的构造方法不
会完成任何事情。下例给出类 AnimationThread的构造
方法,在其初始化过程中设置了一些缺省的数值,比
如帧速度、图片的数目等。
第 6章 Java中类, 对象, 接口及包的概念
class Animation Thread extends Thread {
int frames Per Second;
int num Images;
Image[] images;
Animation Thread(int fps,int num) {
super("Animation Thread");
this.frames Per Second = fps;
this.num Images = num;
this.images = new Image[num Images];
for (int i = 0; i <= num Images; i++) {
第 6章 Java中类, 对象, 接口及包的概念
...
}}
...}
从该例来看, 构造方法的实体跟一般方法的实体
是相似的, 均包含局部变量声明, 循环以及其他的语
句 。 该例的构造方法中出现了以下一条语句:
super("Animation Thread");
第 6章 Java中类, 对象, 接口及包的概念
与关键字 this相似 (我们知道, this表示当前对象 ),
关键字 super表示当前对象的父对象, 所以使用 super可
以引用父类被隐藏的变量和方法 。 本例中调用了父类
Thread的构造方法 。 使用中我们须注意的是, 父类的
构造方法必须是子类构造方法的第一条语句, 因为对
象必须首先执行高层次的初始化 。 构造方法说明中只
能带访问控制修饰符, 即只能使用 public,protected及
private中的任一个 。 关于访问控制符, 后面我们会介绍 。
第 6章 Java中类, 对象, 接口及包的概念
5) 方法 finalize
finalize在 Java程序中相当于 C++中的析构方法, 它
在对象退出的时候释放掉占用的资源 。 其声明格式如
下:
protected void finalize()
{...}
有些面向对象语言需要保持对所有对象的跟踪,
所以在对象不再使用的时候要将它从内存中清除, 这
个过程就是所谓的 "垃圾收集 "。
第 6章 Java中类, 对象, 接口及包的概念
当对象不再有引用的时候, 对象就需被清除, 即
作为垃圾收集的对象 。 保留在变量中的引用通常在变
量超出作用域的时候被清除, 比如当我们从某个方法
调用中退出时, 其局部变量就自动被清除 。 当然也可
以通过设置变量为 null来清除对象引用 。 需注意的是,
程序中同一个对象可以有多个引用, 对象的所有引用
必须在对象被垃圾收集器清除之前清除 。
第 6章 Java中类, 对象, 接口及包的概念
Java有一个立即垃圾收集器, 它周期性地把不再
被引用的对象从内存中清除 。 这个垃圾收集器是自动
执行的, 我们也可以通过调用系统类的 System.gc()方
法来显式地运行垃圾收集程序 (比如在创建大量垃圾代
码之后或者在需要大量内存代码之前运行垃圾收集器 )。
在一个对象被系统垃圾收集器处理之前, 对象也可调
用自己的 finalize方法进行析构处理, 这个过程就是所
说的最后处理, 也有的参考资料称之为结束方法 。
第 6章 Java中类, 对象, 接口及包的概念
Java中构造方法和结束方法在类中均是可选的,尤
其是结束方法在一般情况下是不需要的,而提供结束
方法 finalize的目的是让程序员有机会释放掉不能被自
动内存管理器直接使用的资源或是不能自动释放掉的
资源。
第 6章 Java中类, 对象, 接口及包的概念
6) 变量和方法的访问控制
前面我们多次提到过对类, 变量及方法的访问控
制属性, 比如有,private,friendly,protected及 public。
Java中最低访问控制范围是类的级别, 与之对应也分
为四种:同一个类, 同一个包, 不同包的子类及不同
包的非子类 。
表 6.1给出了每一种访问指示的访问等级 。
第 6章 Java中类, 对象, 接口及包的概念
表 6.1 访问控制权限表
访问指示 类 子类 包 所有
private √
protected √ √ √
public √ √ √ √
friendly √ √
第 6章 Java中类, 对象, 接口及包的概念
表 6.1中, 第二列给出了是否类本身可以访问它的
成员 (从上表可以知道, 类总是可以访问它自己的成员 );
第三列给出了是否类的子类可以访问它的成员;第四
列给出了是否在相同包中的类可以访问该类成员;第
五列给出了是否所有的类可以访问该类成员 。
类的访问控制权限只能为 public和 friendly,变量和
方法的访问控制可以为上面四种的任何一种 。
第 6章 Java中类, 对象, 接口及包的概念
● private
private成员只能被它所定义的类或类的不同对象
所访问 。 外部访问这个变量就会出错, 因为如果
private的方法被外部类调用, 就会使得程序或对象处
于不安全状态 。 private成员就像不能告诉任何人的秘
密, 所以, 任何不需要他人直接访问的成员都应该定
义为 private类型 。
下面的类 A包含了一个 private成员变量和一个
private方法:
第 6章 Java中类, 对象, 接口及包的概念
class A {
private int private Variable;
private void private Method() {
System.out.println("Test for private definition!");} }
在做了以上的定义之后, A类型的对象可以调用
或者修改 private Variable变量以及调用 private Method方
法, 但是其他类型的对象却不行 。 比如, 以下的类 B就
不能访问 private Variable变量或者调用 private Method方
法, 因为类 B不是 A类型的 。
class B {
void access Method() {
第 6章 Java中类, 对象, 接口及包的概念
A a = new A ();
a,privateVariable = 10; //非法
a.privateMethod(); //非法
}}
这时, 编译器就会给出以下错误信息并拒绝继续编译程
序:
B.java:9,Variable privateVariable in class A not accessible
from class B.
//在类 A中的 privateVariable变量不能从类 B中进行访问
a,privateVariable = 10; // 非法
^
1 error //程序中有一个错误
第 6章 Java中类, 对象, 接口及包的概念
与此类似, 如果程序试图访问方法 privateMethod()时, 将
导致如下的编译错误:
B.java:12,No method matching privateMethod()
found in class A,//在类 A中没有匹配的方法
privateMethod()
a.privateMethod(); // 非法
1 error //一个错误
下面我们再给出一个例子来解释同类对象调用
private的方法 。 假如 A类包含了一个实例方法, 它用于
比 较 当 前 的 A 对象 (this) 同 另 外 一 个 对 象 的
privateVariable变量是否相等:
class A {
第 6章 Java中类, 对象, 接口及包的概念
private int private Variable;
boolean is Equal To(A anotherA) {
if (this,Private Variable == another A,private Variable)
return true;
else
return false;}
}
结果是运行正常 。 可见, 相同类型的对象可以访
问其他对象的 private成员 。 这是因为访问限制只是在类
别层次 (类的所有实例 )而不是在对象层次 (类的特定实
例 )上 。
第 6章 Java中类, 对象, 接口及包的概念
实际应用过程中, 如果我们不想让别的类生成自
己定义的类的实例, 可以将其构造方法声明为 private类
型 。 比如, java.lang.System,它的构造方法为 private,
所以不能被实例化, 但由于其所有方法和变量均定义
为 static类型, 故可以直接调用其方法和变量 。
第 6章 Java中类, 对象, 接口及包的概念
● protected
定义为 protected的类成员允许类本身, 子类以及
在相同包中的类访问它 。 一般来说, 需要子类访问的
成员, 可以使用 protected进行限制 。 protected成员就像
家庭秘密, 家里人知道无所谓, 但是却不让外人知道 。
现在我们看看 protected是怎样限制使用在相同包内的类
的 。 假如上面的那个类 A现在被定义在一个包 Protect1
内, 它有一个 protected成员变量和一个 protected方法,
具体如下:
第 6章 Java中类, 对象, 接口及包的概念
package Protext1;
public class A {
protected int protectVariable;
protected void protectMethod() {
System.out.println("Test for protected definition!");}}
现在,假设类 C也声明为 Protect1包的一个成员 (不
是 A的子类 )。则类 C可以合法地访问 A对象的 protect
Variable成员变量并且可以合法调用它的 protect Method,
如下,package Protect1;
第 6章 Java中类, 对象, 接口及包的概念
class C {
void access Method() {
A a = new A ();
a,protect Variable = 10; //合法
a.protect Method(); //合法
}}
下面我们探讨 protected如何限制类 A子类的访问。
首先定义类 D,它由类 A继承而来,但处在不同的包中,
设为 Protect2。则类 D可以访问其本身类实例成员
protect Variable和 protect Method,但不能访问类 A对象
中的 protect Variable或者 protect Method。
第 6章 Java中类, 对象, 接口及包的概念
在下面代码中, access Method试图访问在 A类型对
象中的 protect Variable成员变量, 这是不合法的, 而访
问 D类型对象则是合法的 。 与此相同, access Method
试图调用 A对象的 protect Method方法也是非法的 。 见
下例:
package Protect2;
import Protect1.*;
class D extends A {
void access Method(A a,D d) {
a,protect Variable = 10; //非法
第 6章 Java中类, 对象, 接口及包的概念
d,protect Variable = 10; //合法
a.protect Method(); //非法
d.protect Method(); //合法
}}
● public
public是 Java中最简单的访问控制符 。 修饰为 public
的成员在任何类中, 任何包中都可以访问, 它相当于
是无任何秘密可言, 从其使用角度来看, 有点相当于 C
语言中的外部变量 。 例如:
第 6章 Java中类, 对象, 接口及包的概念
package Public1;
public class A {
public int public Variable;
public void public Method() {
System.out.println("Test for public definition!");}}
接下来, 我们重新编写类 B,将它放置到不同的包中, 并
且让它跟类 A毫无关系:
package Public2;
import Public1.*;
class B {
void access Method() {
第 6章 Java中类, 对象, 接口及包的概念
A a = new A ();
a,public Variable = 10; // 合法
a.public Method(); // 合法
}}
从上面的代码段我们可以看出,这时类 B可以合
法地使用和修改在类 A中的 public Variable变量及方法
public Method。
第 6章 Java中类, 对象, 接口及包的概念
● friendly
friendly关键字我们并不陌生, 在 C++中其表示友
元类, Java中如果不显式设置成员访问控制的时候 (即
缺省的访问控制 ),则隐含使用 friendly访问控制 。 该访
问控制允许在相同包中的类成员之间相互可以访问 。
就像在相同包中的类是互相信任的朋友 。 下例中, 类 A
声明了一个单一包访问的成员变量和方法 。 它处在
Friend包中:
第 6章 Java中类, 对象, 接口及包的概念
package Friend;
class A {
int friend Variable; //缺省为 friendly
void friend Method() //缺省为 friendly
{System.out.println("Test for friendly definition!");}
}
这样,所有定义在和类 A相同的包中的类也可以访问
friend Variable和 friend Method。
第 6章 Java中类, 对象, 接口及包的概念
假如 A和 B都被定义为 Friend包的一部分, 则如下的
代码是合法的:
package Greek;
class B {
void access Method() {
A a = new A ();
a,friend Variable = 10; //合法
a.friend Method(); //合法
}
}
第 6章 Java中类, 对象, 接口及包的概念
6.2 对 象
6.2.1 对象的创建
Java中创建新的对象必须使用 new语句,其一般格
式为 class Name object Name = new class
Name( parameter List);此表达式隐含了三个部分,即:
对象说明、实例化和初始化。
第 6章 Java中类, 对象, 接口及包的概念
● 对象说明:上面的声明格式中,class Name
object Name是对象的说明; class Name是某个类名,用
来说明对象所属的类; object Name为对象名。例如:
Integer I Variable;该语句说明 I Variable为 Integer类型。
● 实例化,new是 Java实例化对象的运算符 。 使用
命令 new可以创建新的对象并且为对象分配内存空间 。
一旦初始化, 所有的实例变量也将被初始化, 即算术
类型初始化为 0,布尔逻辑型初始化为 false,复合类型
初始化为 null。 例如:
Integer I Variable = new Integer (100);
此句实现将 Integer类型的对象 I Variable初始值设
为 100的功能 。
第 6章 Java中类, 对象, 接口及包的概念
● 初始化,new运算符后紧跟着一个构造方法的
调用 。 前面我们介绍过, Java中构造方法可以重构,
因而通过给出不同的参数类型或个数就可以进行不同
初始化工作 。 如例 6.3,类 Rectangle定义了一个矩形类,
它有多个不同的构造方法, 我们可以通过调用不同的
构造方法来进行初始化 。
第 6章 Java中类, 对象, 接口及包的概念
例 6.3
public class Rectangle {
public int width = 0;
public int height = 0;
public Point origin;
public static void main(String args[]){
Point p=new Point(20,20);
Rectangle r1=new Rectangle();
Rectangle r2=new Rectangle(p,80,40);
第 6章 Java中类, 对象, 接口及包的概念
Transcript.println("The area of Rectangle1 is,"+r1.area());
Transcript.println("The area of Rectangle1 is,"+r2.area()); }
public Rectangle() {
origin = new Point(0,0);}
public Rectangle(Point p) {
origin = p;}
public Rectangle(int w,int h) {
this(new Point(0,0),w,h);}
public Rectangle(Point p,int w,int h) {
origin = p; width = w; height = h;}
public void move(int x,int y) {
第 6章 Java中类, 对象, 接口及包的概念
origin.x = x;
origin.y = y;}
public int area() {
return width * height;}
}
public class Point {
public int x = 0;
public int y = 0;
第 6章 Java中类, 对象, 接口及包的概念
图 6.4
第 6章 Java中类, 对象, 接口及包的概念
public Point(int x,int y) {
this.x = x; this.y = y;}
}
该例中, 我们定义了两个类 Rectangle,Point,并
调用了类 Rectangle中的 area()方法来求矩形的面积 。 方
法 Rectangle()不带参数, 因而只是初始化原点坐标为
(0,0),矩形的长, 宽各为 0;方法 Rectangle(p,80,40)不
仅初始化原点由类型 Point()指定, 同时还限定矩形的
长, 宽各为 80,40。 此程序的运行结果如图 6.4所示 。
第 6章 Java中类, 对象, 接口及包的概念
6.2.2 对象的使用
前面我们花了很大的篇幅介绍类, 其目的就是为
了掌握如何使用它 。 类是通过实例化为对象来使用的,
而对象的使用是通过引用对象变量或调用对象的方法
来实现的 。 与 C++相类似, 对象变量和方法均是通过
运算符,,”来实现的 。
1,变量的引用
对象变量引用的一般格式为
object Name.variable Name
第 6章 Java中类, 对象, 接口及包的概念
例如:
class example {
int x; }
example a = new example();
a.x=100;
变量的引用在 Java中还有一种很特殊的情况, 即可
以使用表达式指定变量所在的对象, 例如:
int z= new example().x;
第 6章 Java中类, 对象, 接口及包的概念
这个语句创建了一个新的 example对象, 并且得到
了它的成员变量 x。 需要注意的是, 在这条语句被执行
后, 程序不再保留对象 example的引用 。 这样, 对象
example就被取消引用, 因而通过上述语句并不能达到
初始化对象的作用 。
第 6章 Java中类, 对象, 接口及包的概念
2,对象方法的引用
与对象变量引用一样, 对象方法的引用一般格式为
object Name.method Name([argument List]);
例如我们在例 6.3中调用对象 Rectangle中的 area()方
法计算矩形的面积:
Transcript.println("The area of Rectangle1 is,"+r1.area());
Transcript.println("The area of Rectangle1 is,"+r2.area());
第 6章 Java中类, 对象, 接口及包的概念
虽然通过直接引用对象变量可以改变对象的属性,
但是它没有任何意义 (比如,我们在例 6.3中,使用
Rectangle类的构造方法,可以创建不同的矩形,如果设
置其高 height、宽 width是负的,程序并不认为其非法 )。
所以,较好的做法是:不直接对变量进行操作,而由类
提供一些方法,对变量的引用可以通过这些方法来进行,
以确保给定变量的数值是有意义的。这样一来,
Rectangle类将提供 setWidth,setHeight,getWidth以及
getHeight方法来设置或者获得宽度和高度。设置变量的
方法将在调用者试图将 width和 height设置为负数的时候
给出一个错误。这样能够更好地体现数据的封装和隐蔽。
例如,加上上述的几个方法后,例 6.3变为
第 6章 Java中类, 对象, 接口及包的概念
public class Rectangle
{
...
public void setWidth(int width) {
if (width < 0)
System.out.println("Illegal number! ");
else
this.width=width; }
public void setHeight(int height) {
...}
第 6章 Java中类, 对象, 接口及包的概念
public int getWidth() {
return width; }
public int getHeight(){
return height;}
public void move(int x,int y) {
origin.x = x; origin.y = y; }
public int area() {
return width * height;
}
}
第 6章 Java中类, 对象, 接口及包的概念
6.3 类的继承概念
Java通过子类实现继承 。 继承指的是某个对象所
属的类在层次结构中占一定的位置, 具有上一层次对
象的某些属性 。 在 Java中, 所有的类都是通过直接或
间接地继承 java.lang.Object类得到的, 如图 6.5所示 。
第 6章 Java中类, 对象, 接口及包的概念
图 6.5
第 6章 Java中类, 对象, 接口及包的概念
在类的继承过程中, 被继承的类为父类或超类,
继承得到的类为子类 。 父类包括所有直接或间接被继
承的类 。 子类继承父类的状态和行为, 也可以修改父
类的状态或重写父类的行为 (方法 ),同时也可以再添加
新的状态和行为 (方法 )。 需要注意的是, Java与 C++不
同, 不支持多重继承 。 同时, 为了使继承更为灵活和
完善, Java支持最终类和抽象类的概念 。
第 6章 Java中类, 对象, 接口及包的概念
所谓的最终类, 同数结构中的树叶节点一样, 就
是不允许对它进行扩展的类, 也就是说不可以有该类
的子类 。 实际使用过程中, 可以在定义类时用关键字
final对它加以说明 。 引入最终类的好处是为了提高系
统安全性, 因为如果有重要的信息的类允许继承的话,
就可能被不怀好意的攻击者加以利用, 从而重要的数
据就可能被非法修改或泄密 。 为了防止这些情况发生,
可以将那些重要的类说明为最终类, 避免非安全事件
的发生 。
第 6章 Java中类, 对象, 接口及包的概念
Java中, 类层次的另一个概念就是抽象类, 它与最
终类相对, 需要子类继承完善 。 在类的说明中我们已
讨论过, 这里不再详细说明, 只是有几点注意事项希
望读者留意:
(1) 构造方法不能定义为抽象方法 。
(2) 最终方法不能说明为抽象方法 。
(3) static和 private修饰符不能用于抽象方法 。
(4) 不能重载父类中的抽象方法 。
第 6章 Java中类, 对象, 接口及包的概念
6.3.1 子类的创建
通过关键字 extends来创建某个类的子类, 其语法如下:
class subclass Name extends superclass Name {...}
例如:
class Rectangle extends Shape {...}
这样, 类 Rectangle就可以继承父类 Shape中的成员
变量和方法 。 前面一些例子中, 在作类的定义时, 并
没有指明继承于某个父类, 比如:
public class Rectangle {,.,}
第 6章 Java中类, 对象, 接口及包的概念
此时, 隐含认为类 Rectangle缺省继承于类 Object。
当然, 继承父类中的 private属性的变量和方法也是受限
制的, 这是大家需要注意的地方 。 我们可以发现, 通
过继承的关系, 使得成熟的代码可以获得重用的好处,
大大提高了编程的效率 。 同时, 由类封装而带来的数
据隐藏, 也可以提高程序的可维护性 。
第 6章 Java中类, 对象, 接口及包的概念
6.3.2 变量的隐藏
继承给我们带来方便, 但如果使用中概念不清,
也可能会给我们带来一些问题 。 假设我们实现了某个
类的继承, 当子类中的成员变量与父类中的成员变量
同名时, 应该怎么办呢? Java解决这一问题的办法是
采用所谓的变量隐藏机制 。 也就是说, 如果该种情况
发生, 则父类中的变量将被隐藏起来 。 例如:
class super Class {
int same Variable;
...}
第 6章 Java中类, 对象, 接口及包的概念
class sub Class extends super Class{
int same Variable
// 此时, 此处变量 same Variable隐藏了父类的同
名变量
...}
可能有的读者会说,那我非要用父类中的同名变
量,应该怎么办呢?其实我们前面讨论构造方法时已
经提到过:当引用父类中的变量时,必须使用 super关
键字。
第 6章 Java中类, 对象, 接口及包的概念
class sub Class extends super Class{
int same Variable
//此时, 此处变量 same Variable隐藏了父类的同名变量
...
System.out.println( "Now output the Super Class variable!
" + super.sameVariable);
//引用父类中的变量
}
第 6章 Java中类, 对象, 接口及包的概念
6.3.3 方法置换
与我们前面所介绍的方法重载很相似, Java中的方
法置换指的是子类中的方法名与父类中的某个方法名
相同, 此时, 子类中的同名方法就被称为置换方法 。
置换方法与父类中的同名方法具有相同的方法名, 相
同的返回值类型和相同的参数表 。 如果要调用父类中
的同名方法, 也使用关键字 super进行前缀修饰 。 例如:
第 6章 Java中类, 对象, 接口及包的概念
例 6.4
package untitled4;
import genesis.*;
public class MyClass1 {
int x,y;
public MyClass1(){ }
public MyClass1(int x,int y) {
this.x=x; this.y=y; }
public void test(){
Transcript.println("x,y in superclass is,"+x+" "+y);}
第 6章 Java中类, 对象, 接口及包的概念
}
package untitled4;
import genesis.*;
public class MyClass2 extends MyClass1 {
int x,y;
public MyClass2(int x,int y) {
this.x=x;
this.y=y; }
public static void main(String args[]){
MyClass2 m2= new MyClass2(10,20);
MyClass1 m1=m2;
m1.test(); m2.test();}
第 6章 Java中类, 对象, 接口及包的概念
public void test(){
super.test();
Transcript.println("x,y in subclass is,"+ x+" "+y);
}}
运行结果如图 6.6所示 。 请读者仔细分析程序的执行结果 。
第 6章 Java中类, 对象, 接口及包的概念
图 6.6
第 6章 Java中类, 对象, 接口及包的概念
6.4 Java中接口与包的概念
在上一小节我们讨论了 Java中的一个重要特征:继
承机制 。 由于 Java只支持单一继承, 即一个子类只有
一个父类 (与 C++不同 ),但实际的开发过程中, 可能会
碰到需要多重继承的情况, 这应该怎么办呢? Java中
的接口机制为我们提供了实现多重继承的可能 。 接口
的概念较 C++中的多重继承概念要简单, 方便, 它可
以达到多个不相关的类具有相同的方法这一特殊效果 。
第 6章 Java中类, 对象, 接口及包的概念
6.4.1 接口
接口是一系列没有实现的方法和常量的组合, 它
提供方法协议的封装, 但不限制子类如何实现这些方
法, 从而使得类的继承变得简单而灵活 。 通过接口我
们可以使处于不同层次, 互不相干的类具有相同的行
为 。 总的来说, 接口的功能可以归纳为如下几点:
第 6章 Java中类, 对象, 接口及包的概念
(1) 通过接口可以实现不相干类的相同行为而不需
考虑这些类之间的层次关系 。
(2) 通过接口可以指明多个类需要实现的方法 。
(3) 通过接口可以了解对象的交互界面而不需了解
对象所对应的类 。
Java中的接口的基本组成如图 6.7所示 。
第 6章 Java中类, 对象, 接口及包的概念
public interface inter face Name {
final String name="Name";
final String sex="male";
...
void aInter face Example(parameter List);
}
第 6章 Java中类, 对象, 接口及包的概念
图 6.7
public interface interfaceName {
final String name="Name";
final String sex="male";
…
void aInterfaceExample(parameterList);
}
接口声明
接口体
常量定义
方法声明
第 6章 Java中类, 对象, 接口及包的概念
图 6.7给出了一个接口的常见声明格式 。 接口声明
定义了各种关于接口的属性, 如它的名字和是否扩展
其他的属性等;接口实体包含了常数和用于接口的方
法声明 。
1,接口的声明
与类的声明格式相似, 接口的声明格式如下:
Modifiers interface inter face Name
[extends superinter face_List]
{inter face Body}
第 6章 Java中类, 对象, 接口及包的概念
在接口定义中, 必须有两个元素,interface关键字
和接口的名字, 其他均为可选项 。 如果访问限制为
public,则表示接口可以在任何包的任何类中使用 。 如
果没有指定接口为 public,那么接口就只能在定义接口
的包的类中使用了 。 接口隐含修饰符为 abstract,当然,
也可以显式指明为 abstract,但是没有必要 。
第 6章 Java中类, 对象, 接口及包的概念
接口定义可以有另外一个选项,superinter
face_List系列。一个接口可以通过关键字 extends扩展另
外的接口,这跟类可以扩展的概念一样。但是,类只
能扩展一个另外的类,而接口可以扩展任意多个接口。
Superinter face_List系列以逗号 (,)分隔的所有接口,
这些接口可以由新的接口扩展。我们知道,在类的扩
展中,所有的类,其超类均为 Object,而接口没有所谓
的超接口。
接口实体为所有包含在接口中的方法及变量 。
第 6章 Java中类, 对象, 接口及包的概念
所有定义在接口中的方法隐含为 public和 abstact。
所有定义在接口中的常量可以是 public,static和
final,接口中的变量隐含为静态变量 (static)。 定义在接
口中的成员声明不允许使用某些声明修饰语, 比如不
能在接口中的成员声明中使用 transient,volatile或者
synchronized。 同样, 不能在声明接口成员的时候使用
private和 protected修饰语 。
第 6章 Java中类, 对象, 接口及包的概念
另外一点需要注意的是, 接口中的方法不能有方法体,
所以实现接口的类必须实现接口中的所有方法 。 例如:
public interface My inter face extends superinter face{
String name;
final int x=10;
void My method(int x,int y);
...}
第 6章 Java中类, 对象, 接口及包的概念
2,接口的实现
Java中提供接口的目的当然是为了使用它,用户
定义的类要使用某个接口时,必须首先实现这一接口。
可以通过关键字 implements说明该类要实现的一个或多
个接口,之后在类体中完成接口所有方法的代码。如
此才能使用被实现了的方法。实际使用中,可能会碰
到实现接口的类是抽象类,这样,完善接口方法的任
务就必须由该类的子类来完成。
例如:
第 6章 Java中类, 对象, 接口及包的概念
public class inter face Example implements Runnable{
Thread my Thread;
...
public void run(){
..,//实现接口中的
Runnable方法
}
...}
第 6章 Java中类, 对象, 接口及包的概念
当定义一个新的接口时,从本质上讲,就好像定
义了一个新的引用数据类型。可以在使用其他类型的
名字 (比如变量声明、方法参数等等 )的地方,使用接口
名字。这样我们就可以不必知道对象的精确类型,只
需知道接口的行为,增加了程序的方便性。例如:
public class My class implements On einter face {
...
void doMethod(int x) {
..,//实现接口中的某方法
}
...}
第 6章 Java中类, 对象, 接口及包的概念
public class Useinter face As Para {
int x;
My class m=new My class();
...
void passinter faceAsPara(On einter face m) {
m.do Method(x);
}
...}
第 6章 Java中类, 对象, 接口及包的概念
6.4.2 包 (package)的基本概念
为了使得类更容易地被发现和使用,以及避免名字
空间的冲突、控制访问,Java不支持全局变量和全局
方法,程序员要捆绑相关的类和接口到包中,所有变
量和方法都是在类中定义,而每个类又是包的一部分。
变量和方法都可以用全限定的名字表示,该表示方法
包括包名、类名和类成员名三个组成部分,各部分之
间用,.”符号分隔开,同时包本身也可以用该分隔符组
成的域指明。
第 6章 Java中类, 对象, 接口及包的概念
例如:基本类是在 java.lang中, 而用于阅读和书写
的类在 java.io中等等 。 我们也可以放置自己的类和接口
到某个包中 。 比如在例 6.4中, 首行语句为
package untitled4;
由于我们在 JBuilder3中进行属性设置时把根目录源
路径设置为
c:\JBuilder3\myprojects;
则语句, package untitled4;”表达的意思就是该包
所处的位置为
c:\JBuilder3\myprojects\untitled4
第 6章 Java中类, 对象, 接口及包的概念
这样, 当我们对类 Myclass1及 Myclass2进行编译后,
得到的两个字节码文件 Myclass1.class,Myclass2.class
均在此目录下 。 所以, 包名实际上是,class文件的绝对
路径 。 如果我们使用的是 JDK,则路径的说明必须由
环境变量 CLASSPATH进行定义 。
1,包的定义
我们知道, Java中的包与 C/C++中的 #include语句
及 Pascal语言中的 Unit语句相类似, package语句的一般
形式为
package package Name;
第 6章 Java中类, 对象, 接口及包的概念
我们常常把自己设计的类或接口组成一个或多个
包, 使得功能相近, 用途相同, 关系密切的类和接口
纳入一个包中 。 从前面我们介绍的访问控制属性中大
家知道, 同一个包中的类或接口相互之间的访问权限
要高于与它们不在同一个包中的类或接口 。 这样, 当
我们设计类的时候只要划分好包的层次, 就可以使处
于包中的类或接口的功能与本类提供的功能相协调 。
例如在例 6.4中, 类 MyClass1及类 MyClass2二者开头的
一条语句均为
package untitled4;
第 6章 Java中类, 对象, 接口及包的概念
表明二者处在同一个包中,之后经编译所形成
的,class也是处在同一个目录下。这样才能充分利用包
机制所提供的类组织以及由此而带来的更为灵活方便
的代码重用。
2,包的引入
一般来说,java.lang包中定义了基本的类和接口,
当编译的时候,Java编译器会自动将所需要的内容引
入。如果要引入用户自定义的包,可以使用 import语句
引入。该语句的功能是引入包或包中的类,从而使得
当前类可以用省略的形式来使用包中的类或接口。
第 6章 Java中类, 对象, 接口及包的概念
有:
① import package Name;
② import package Name.class;
③ import package.*;
这三种格式大致相同, 但存在一些细微的区别 。
第一种格式允许只用包名中的最后一部分来指定包名,
例如:
import java.lang.String;
第 6章 Java中类, 对象, 接口及包的概念
这样, 今后就可以直接使用包中 String类的变量和
方法 (如果最后项所指为类 ),当最后项为包时, 则可以
直接使用对应包中的类及方法 。 第二种格式与第一种
相似, 只是所指为确定的某一类 。 第三种格式最常用,
其功能为使包中的所有类都可以用其类名直接访问,
例如:
import java.lang.*;
第 6章 Java中类, 对象, 接口及包的概念
与 C/C++类似, import 语句在程序中也可以有任意
多个, 只是必须清楚引入的包中是否有本人需要的类,
例如:
import java.awt.*;
import java.net.*;
第 6章 Java中类, 对象, 接口及包的概念
3,Java中的常用包
C中的头文件 io.h,string.h是比较常用的,与此相
同,Java也有一些编程中常用的包、类和接口。例如
字符串处理、网络开发、窗口调用、数学计算及异常
处理等等。这里,为了更好的理解,我们给出 Java中
常用的包,它与 Windows一样,集成为一个应用程序
借口 API(Application Programming Interface),如表 6.2
所示
第 6章 Java中类, 对象, 接口及包的概念
表 6.2 常用包列表
包 名 功 能 描 述
java.applet 使用 Applet的类和接口
java.awt Java抽象窗口工具集
java.awt.image 图像处理类
java.awt.peer 使 Java的窗口系统跨平台移植的类和接口
java.io 输入 /输出类和接口
java.lang Java的核心类, 包括字符串, 数学计算, 异常处理等
java.net 网络应用类和接口
java.util 优化程序设计的一些类, 如矢量队列等
javax.swing 扩展的一些 Java类和接口
第 6章 Java中类、对象、接口及
包的概念
6.1 类的基本概念
6.2 对象
6.3 类的继承概念
6.4 Java中接口与包的概念
第 6章 Java中类, 对象, 接口及包的概念
6.1 类的基本概念
传统的过程式语言, 如 C,由于它的设计方式与客
观世界之间存在差距, 使得程序的编写首先必须定义
所要实现的功能, 然后确定需采取的步骤, 即所谓的
,逐步求精, 的结构程序设计方法 。 实际开发中, 当
程序大到一定程度的时候, 其调试和维护就变得很困
难, 使用过程式语言就会感到力不从心了 。
第 6章 Java中类, 对象, 接口及包的概念
前面我们说过, Java是一种纯面向对象的编程语
言, 而面向对象程序设计是近些年来才发展起来的程
序设计方法, 其基本思想是将现实世界中的事物抽象
为对象, 抽象出来的对象被赋给相应的状态和行为,
通过对消息的响应完成一定的任务 。 在现实生活中,
任何事物都可以被认为是对象 (Object),如:
① 电梯
② 街头的自动售货机
③ 街上跑的汽车
④ 凳子
⑤ 人
……
第 6章 Java中类, 对象, 接口及包的概念
上面列举的对象都有两个共性:
(1) 具有一定的状态和特性 。 比如汽车有轮胎, 发
动机, 方向盘等 。
(2) 每个对象对应一组特定的操作 。 比如汽车需保
养, 加油, 清洗等 。
面向对象程序设计方法就是把现实世界中对象的
状态和操作抽象为程序设计语言中的对象,达到二者
的统一。同一种对象的所有共性进行抽象,又得到了
类的概念。
第 6章 Java中类, 对象, 接口及包的概念
所以, 面向对象程序设计中的对象是由描述状态
的变量和对这些变量进行维护和操作的一系列方法组
成的事务处理单位, 而类相当于创建对象实例的模板,
通过对其实例化得到同一类的不同实例 。 本章我们将
讨论类的特性, 成员变量, 方法, 对象的建立及初始
化, 对象的继承及接口与包等内容 。
第 6章 Java中类, 对象, 接口及包的概念
类是对一个或几个相似对象的描述, 它把不同对
象具有的共性抽象出来, 定义某类对象共有的变量和
方法, 从而使程序员实现代码的复用, 所以说, 类是
同一类对象的原型 。 创建一个类, 相当于构造一个新
的数据类型, 而实例化一个类就得到一个对象 。 Java
为我们提供了大量的类库, 如果从已知类库入手来构
造自己的程序, 不仅能有效地简化程序设计, 而且能
很好地学习面向对象程序设计方法 。
其实, 前面很多例子已经对类的组成有了明确地
说明, 一个类的实现包含两部分内容:声明和实体 。
类的各部分组成如图 6.1所示 。
第 6章 Java中类, 对象, 接口及包的概念
图 6.1
p u b l i c c l a s s s t a c k
{
p r i v a t e V e c t o r i t e m s ;
p u b l i c S t a c k ( ) {
i t e m s = n e w V e c t o r ( 1 0 ) ;
}
p u b l i c O b j e c t p u c h ( O b j e c t i t e m ) {
i t e m s, a d d E l e m e n t ( i t e m ) ;
r e t u r n i t e m ;
}
p u b l i c s y n c h r o n i z e d O b j e c t p o p ( ) {
i n t l e n = i t e m s, s i z e ( ) ;
O b j e c t o b j = n u l l ;
i f ( l e n = = 0 )
t h r o w n e w E m p t y S t a c k E x c e p t i o n ( ) ;
o b j = i t e m s, E l e m e n t A t ( l e n - 1 ) ;
i t e m s, r e m o v e E l e m e n t A t ( l e n - 1 ) ;
r e t u r n o b j ;
}
p u b l i c b o o l e a n i s E m p t y ( ) {
i f ( i t e m s, s i z e ( ) = = 0 )
r e t u r n t r u e ;
e l s e
r e t u r n f a l s e ;
}
}
类的实体
类的声明
变量定义
构造函数
方法定义
第 6章 Java中类, 对象, 接口及包的概念
6.1.1 类的声明
类声明包括关键字 class,类名及类的属性 。 类名
必须是合法的标识符, 类的属性为一些可选的关键字 。
其声明格式如下:
[public|private|friendly|protected] [abstract][final] class
className
[extends superclassName][implements interfaceNameList]
{...}
其中,第一项属于访问控制符,它不仅针对于类,
类的变量、方法的访问也有该项的限制,我们后面会
做专门的介绍。其他的修饰符说明如下:
第 6章 Java中类, 对象, 接口及包的概念
● abstract:声明该类不能被实例化 。
● final:声明该类不能被继承, 即没有子类 。
● class class Name:关键字 class告诉编译器表示类的声
明以及类名是 class Name。
● extends super class Name,extends 语句扩展 super class
Name为该类的父类。
第 6章 Java中类, 对象, 接口及包的概念
● implements interface Name List:声明类可实现
一个或多个接口, 可以使用关键字 implements并且在其
后面给出由类实现的多个接口名字列表, 各接口之间
以逗号分隔 。 如图 6.1中的
public class stack
{...}
即为类的声明 。
第 6章 Java中类, 对象, 接口及包的概念
6.1.2 类的实体
类体是类的主要部分, 包括变量的说明及该类所
支持的方法, 我们习惯称之为成员变量和成员方法 。
需要注意的是, 除了类体中定义的变量与方法外, 该
类还继承了其父类的变量与方法 。 当然, 对父类变量
和方法的访问要受到访问控制条件的限制 。 类体说明
的格式为
class class Name {
variable Declaration
method Declaration
}
第 6章 Java中类, 对象, 接口及包的概念
读者可参照图 6.1仔细体会类体所包含的内容 。
1,变量
Java中变量的说明可以分为两种:类成员变量的说
明和方法变量的说明 。 其变量声明格式为
[public|protected|private] [static][final] [transient][volatile]
type variable Name
上述声明格式中, 第一项指的是访问控制格式 (我
们后面会有介绍 ),另外的几项我们说明如下:
第 6章 Java中类, 对象, 接口及包的概念
● static,成员控制修饰符, 说明该类型的变量为静
态变量, 或者称之为类变量 。 说明静态变量类型后则
该类的所有实例对象都可以对其共享, 而且访问静态
变量无须事先初始化它所在的类 。
● final:常量声明修饰符, 与 C/C++类似, 用该符
号声明后, 在程序的运行过程中不能再改变它的值 。
实际使用中, final往往与 static结合在一起使用 。 比如:
final int INDEX = 1000;
static final int LOOP=10;
第 6章 Java中类, 对象, 接口及包的概念
● volatile:异步控制修饰符, 表示多个并发线程
共享的变量, 这使得各线程对该变量的访问保持一致 。
● transient:存储控制临时变量修饰符, 因为在
缺省的情况下, 类中所有变量都是对象永久状态的一
部分, 将对象存档时, 必须同时保存这些变量 。 用该
限定词修饰的变量指示 Java虚拟机:该变量并不属于
对象的永久状态 。 它主要用于实现不同对象的存档功
能 。
总之, 从变量定义的不同位置及所使用的限定词
不同来看, 变量可以分为三类:实例变量, 局部变量
和静态变量 。
第 6章 Java中类, 对象, 接口及包的概念
如果在类的方法代码段之外声明且没有限定词
static,则为实例变量 。 从它的定义我们可以看出, 实
例变量与类紧密相关, 如果一个类有多个实例对象,
那么每个实例对象都有自己的实例变量拷贝, 之间并
不影响 。
第 6章 Java中类, 对象, 接口及包的概念
如果在类的方法本体之中声明, 则为局部变量,
这有点与 C语言函数中定义的局部变量相似 。 由于局部
变量是在方法体内所定义, 因而只能在本方法中使用,
无所谓访问控制, 也不能用 static修饰符加以说明 。 另
外, 需要注意的是局部变量使用前必须初始化, 这也
是它与实例变量及后面要介绍的静态变量之间的不同
之处 。 局部变量可以与实例变量同名而相互不影响 。
如果将一个实例变量声明为 static,则为静态变量,
或称之为类变量 。 静态变量在类声明后就可以直接引
用, 但实例变量则不能, 必须在实例化对象后才可以
使用 。
第 6章 Java中类, 对象, 接口及包的概念
下面我们对实例变量与类变量加以详细地说明,
以加深读者的理解 。 比如我们可以如下来声明一个成
员变量:
class My Class {
public float variable1;
public static int variable2
}
第 6章 Java中类, 对象, 接口及包的概念
该例中声明了一个实例变量 variable1和一个类变
量 variable2。 今后当我们创建类的实例的时候, 系统就
会为该实例创建一个类实例的副本, 但系统为每个类
分配类变量仅仅只有一次, 而不管类创建的实例有多
少 。 当第一次调用类的时候, 系统为类变量分配内存 。
所有的实例共享了类的类变量的相同副本 。 在程序中
可通过一个实例或者类本身来访问类变量 。 例如:
…
My Class A=new My Class();
My Class B=new My Class();
第 6章 Java中类, 对象, 接口及包的概念
A.variable1=100;
A.variable2=200;
B.variable1=300;
B.variable2=400;
System.out.println("A.variable1= "+A.variable1);
System.out.println("A.variable2= "+A.variable2);
System.out.println("A.variable1= "+A.variable1);
System.out.println("A.variable1= "+A.variable1);
...
第 6章 Java中类, 对象, 接口及包的概念
当我们从类实例化新对象的时候, 就得到了类实例
变量的一个新副本 。 这些副本跟新对象是联系在一起的 。
因此, 每实例化一个新 MyClass对象的时候, 就得到了
一个和 MyClass对象有联系的 variable1的新副本 。 当一个
成员变量用关键字 static被指定为类变量后, 其第一次调
用的时候, 系统就会为它创建一个副本, 之后, 类的所
有实例均共享了该类变量的相同副本 。 所以上述程序段
的输出结果为
A.variable1= 100
A.variable2= 400
B.variable1= 300
B.variable2= 400
第 6章 Java中类, 对象, 接口及包的概念
2,方法
Java程序通过方法完成对类和对象属性的操作。方法
定义了在类成员变量上的一系列操作,它只能在类的内
部声明并加以实现,其他的对象通过调用对象的方法得
到该对象的服务。方法的定义包含两部分内容:方法声
明和方法体。
1) 方法声明
方法声明的一般格式如下:
[public/protected/private][static][final][abstract]
[native][synchronized]
return Type method Name([param List]) [throws
exceptionList]
{...}
第 6章 Java中类, 对象, 接口及包的概念
在方法声明中应包括方法名, 方法的返回值类型,
方法的修饰词, 参数的数目和类型及方法可能产生的
例外 。 从其声明格式中可以发现, 不一定要全部显示
并指明所有的信息, 方法最基本的声明格式为
return Type method Name()
{...}
一般声明格式中的第一项是访问控制属性, 后面
会介绍 。 其他几个修饰词我们说明如下:
第 6章 Java中类, 对象, 接口及包的概念
● static,说明该方法为静态方法。与变量的定义
类似,静态方法我们也称作类方法,与之对应,其他
的方法就为实例方法。静态方法属于类,所以只要对
类作了声明,就可以调用该类的类方法,即使用时无
须类的初始化。当然,实例方法只能在类的实例或子
类的实例中调用。类方法只能操作类变量而不能访问
定义在类中的实例变量,这是实际使用过程中经常出
错的地方。例如:
第 6章 Java中类, 对象, 接口及包的概念
class A {
int x;
static public int x() {
return x;}
static public void setX(int newX) {
x = newX;}
}
...
A myX = new A ();
A anotherX = new A ();
第 6章 Java中类, 对象, 接口及包的概念
myX.setX(1);
anotherX.x = 2;
System.out.println("myX.x = " + myX.x());
System.out.println("anotherX.x = " + anotherX.x());
...
当我们编译的时候, 编译器会给出以下的错误信息:
A.java:4,Can't make a static reference to
nonstatic variable x in class A.
return x;
第 6章 Java中类, 对象, 接口及包的概念
^
出现这个错误的原因是类方法不能访问实例变量, 如果
把类的定义改为
class AnIntegerNamedX {
static int x;
static public int x() {
return x;}
static public void setX(int newX) {
x = newX;}
}
第 6章 Java中类, 对象, 接口及包的概念
类就可以成功编译了:
myX.x = 2
anotherX.x = 2
实例成员和类成员之间的另外不同点是类成员可以在类
本身中访问, 而不必实例化一个类来访问类成员 。
第 6章 Java中类, 对象, 接口及包的概念
下面再对上面的代码进行修改:
...
A.setX(1);
System.out.println("A.x = " + A.x());
...
这里我们不用实例化类对象 myX和 anotherX就可以
直接从类 A中设置 x并输出 x。 这样同样可以得到类变量
x的值 。
第 6章 Java中类, 对象, 接口及包的概念
● abstract,说明一个方法是抽象方法, 即该方法
只有方法说明而没有方法体 。 抽象方法的实现须由该
方法所在类的子类来实现 。 如果一个类包含一个或多
个抽象方法, 则该类必须为抽象类 。 抽象类不能被实
例化 。 例如:
class Shape{
abstract void draw();}
该例中的说明方法 draw()为抽象方法 。
第 6章 Java中类, 对象, 接口及包的概念
● final,final方法类似于常量的定义,它说明一
个方法为终极方法,即它不能被子类重载。说明为
final的方法往往与关键字 private一起使用,避免出错。
例如:
...
private final meth_final()
{...}
第 6章 Java中类, 对象, 接口及包的概念
● native,synchronized:程序中 native指明本方
法是用与平台有关的开发语言编写的,也就是说用来
把 Java代码和其他语言的代码集成在一起。
synchronized主要用于多线程程序设计,说明某一方法
是同步方法,用来控制多个并发线程对共享数据的访
问。我们后面在讲线程的时候还要作介绍。
第 6章 Java中类, 对象, 接口及包的概念
2) 方法重载
Java中方法的重载指的是多个方法共用一个名字
(这样可实现对象的多态 ),同时, 不同的方法要么参数
个数各不相同, 或者是参数类型不同 。 Java提供的标
准类中包含了许多构造函数, 并且每个构造函数允许
调用者为新对象的不同实例变量提供不同的初始数值 。
比如, java.awt.Rectangle就有三个构造函数:
Rectangle(){};
Rectangle(int width,int height){};
Rectangle(int x,int y,int width,int height){};
当我们传递不同的参数时, 构造出来的对象的实
例具有不同的属性 。
第 6章 Java中类, 对象, 接口及包的概念
3) 方法中参数的使用
在方法的声明格式中, 需要指明返回值的类型 。
当一个方法不需要返回值的时候, 其类型说明为 void,
否则方法体中必须包含 return语句 。 返回值既可以是基
本数据类型, 也可以是复杂数据类型 。
在 C语言, PASCAL语言中, 函数, 过程的参数都
存在值传递 /参数传递的问题 。 比如 C语言中如果参数
是指针或数组名则为参数传递 。 我们知道, Java中由
于取消了指针, 不可能像 C一样直接操作内存, 但是由
于对象的动态联编性, 复杂数据类型作参数相当于指
针的使用, 即参数传递, 而基本数据类型作参数传递
则相当于值传递 。 比如下例:
第 6章 Java中类, 对象, 接口及包的概念
例 6.1
class swapByValue {
int x,y;
public swapByValue (int x,int y)
{ this.x=x;
this.y=y; }
public void swap(int x,int y)
{ int z;
z=x; x=y; y=z;}
public static void main(String args[]) {
第 6章 Java中类, 对象, 接口及包的概念
swapByValue s= new swapByValue (3,4);
Transcript.println("Before swap,x= "+s.x+" y= "+s.y);
s.swap(s.x,s.y);
Transcript.println("After swap,x= "+s.x+" y= "+s.y);}
}
运行结果如图 6.2所示 。
第 6章 Java中类, 对象, 接口及包的概念
图 6.2
第 6章 Java中类, 对象, 接口及包的概念
例 6.2
class swapByAddress {
int x,y;
public swapByAddress (int x,int y)
{ this.x=x;
this.y=y; }
public void swap(Integer x,Integer y)
{ Integer z;
z=x; x=y; y=z;
this.x=x.intValue();
this.y=y.intValue(); }
第 6章 Java中类, 对象, 接口及包的概念
public static void main(String args[]) {
swapByAddress s= new swapByAddress (3,4);
Transcript.println("Before swap,x= "+s.x+" y= "+s.y);
s.swap(new Integer(s.x),new Integer(s.y));
Transcript.println("After swap,x= "+s.x+" y= "+s.y);
} }
运行后的结果如图 6.3所示 。
第 6章 Java中类, 对象, 接口及包的概念
图 6.3
第 6章 Java中类, 对象, 接口及包的概念
在例 6.1和例 6.2中均出现了一个关键字 this,它起
什么作用呢? Java中关键字 this表示当前对象 。 因为实
际程序编写过程中, 可能会出现局部变量名和成员变
量名同名, 如例 6.3中有:
class swap By Address {
int x,y;
public swap By Address (int x,int y)
{ this.x=x;
this.y=y; }
第 6章 Java中类, 对象, 接口及包的概念
其中, 对象 swapByAdress中定义了两个成员变量 x、
y,同时方法 swapByAddress中也出现了以 x,y命名的
局部变量, 为了避免由此可能造成的二义性, 程序中
我们用 this关键字作前缀修饰词来指明是当前对象的实
例变量 。 与此类似, 用 this关键字同样可以调用当前对
象的某个方法 。
第 6章 Java中类, 对象, 接口及包的概念
4) 构造方法
构造方法用来初始化新创建的对象 。 类可以包含
一个或者多个构造方法, 不同的构造方法根据参数的
不同来决定要初始化的新对象的状态 。 所有的 Java类
都有构造方法, 它用来对新的对象进行初始化 。 构造
方法与类的名字是相同的 。 比如, Stack类的构造方法
的名字为 Stack,而 Rectangle类的构造方法的名字为
Rectangle,Thread类的构造方法的名字为 Thread。 下面
给出 Stack类的构造方法:
第 6章 Java中类, 对象, 接口及包的概念
public Stack() {
items = new Vector(10); }
Java支持对构造方法的重载, 这样一个类就可以
有多个构造方法, 所有的构造方法的名字都是相同的,
只是所带参数的个数和类型相异而已 。 下面是类 Stack
的另一个构造方法 。 这个构造方法是根据它的参数来
初始化堆栈的大小 。
public Stack(int initial Size) {
items = new Vector(initial Size); }
第 6章 Java中类, 对象, 接口及包的概念
从上面可以看出, 两个构造方法都有相同的名字,
但是它们有不同的参数列表 。 编译器会根据参数列表
的数目以及类型来区分这些构造方法 。 所以, 当创建
对象的时候, 要根据它的参数是否与初始化的新对象
相匹配来选择构造方法 。 根据传递给构造方法参数的
数目和类型, 编译器可以决定要使用哪个构造方法 。
如对于下面的代码, 编译器就可以知道应该是使用单
一的整型参数来初始化对象:
new Stack(10);
第 6章 Java中类, 对象, 接口及包的概念
与此相同, 当我们给出下面代码的时候, 编译器
选择没有参数的构造方法或者缺省的构造方法进行初
始化:
new Stack();
另外,如果生成的类不为它提供构造方法,系统
会自动提供缺省的构造方法。这个缺省的构造方法不
会完成任何事情。下例给出类 AnimationThread的构造
方法,在其初始化过程中设置了一些缺省的数值,比
如帧速度、图片的数目等。
第 6章 Java中类, 对象, 接口及包的概念
class Animation Thread extends Thread {
int frames Per Second;
int num Images;
Image[] images;
Animation Thread(int fps,int num) {
super("Animation Thread");
this.frames Per Second = fps;
this.num Images = num;
this.images = new Image[num Images];
for (int i = 0; i <= num Images; i++) {
第 6章 Java中类, 对象, 接口及包的概念
...
}}
...}
从该例来看, 构造方法的实体跟一般方法的实体
是相似的, 均包含局部变量声明, 循环以及其他的语
句 。 该例的构造方法中出现了以下一条语句:
super("Animation Thread");
第 6章 Java中类, 对象, 接口及包的概念
与关键字 this相似 (我们知道, this表示当前对象 ),
关键字 super表示当前对象的父对象, 所以使用 super可
以引用父类被隐藏的变量和方法 。 本例中调用了父类
Thread的构造方法 。 使用中我们须注意的是, 父类的
构造方法必须是子类构造方法的第一条语句, 因为对
象必须首先执行高层次的初始化 。 构造方法说明中只
能带访问控制修饰符, 即只能使用 public,protected及
private中的任一个 。 关于访问控制符, 后面我们会介绍 。
第 6章 Java中类, 对象, 接口及包的概念
5) 方法 finalize
finalize在 Java程序中相当于 C++中的析构方法, 它
在对象退出的时候释放掉占用的资源 。 其声明格式如
下:
protected void finalize()
{...}
有些面向对象语言需要保持对所有对象的跟踪,
所以在对象不再使用的时候要将它从内存中清除, 这
个过程就是所谓的 "垃圾收集 "。
第 6章 Java中类, 对象, 接口及包的概念
当对象不再有引用的时候, 对象就需被清除, 即
作为垃圾收集的对象 。 保留在变量中的引用通常在变
量超出作用域的时候被清除, 比如当我们从某个方法
调用中退出时, 其局部变量就自动被清除 。 当然也可
以通过设置变量为 null来清除对象引用 。 需注意的是,
程序中同一个对象可以有多个引用, 对象的所有引用
必须在对象被垃圾收集器清除之前清除 。
第 6章 Java中类, 对象, 接口及包的概念
Java有一个立即垃圾收集器, 它周期性地把不再
被引用的对象从内存中清除 。 这个垃圾收集器是自动
执行的, 我们也可以通过调用系统类的 System.gc()方
法来显式地运行垃圾收集程序 (比如在创建大量垃圾代
码之后或者在需要大量内存代码之前运行垃圾收集器 )。
在一个对象被系统垃圾收集器处理之前, 对象也可调
用自己的 finalize方法进行析构处理, 这个过程就是所
说的最后处理, 也有的参考资料称之为结束方法 。
第 6章 Java中类, 对象, 接口及包的概念
Java中构造方法和结束方法在类中均是可选的,尤
其是结束方法在一般情况下是不需要的,而提供结束
方法 finalize的目的是让程序员有机会释放掉不能被自
动内存管理器直接使用的资源或是不能自动释放掉的
资源。
第 6章 Java中类, 对象, 接口及包的概念
6) 变量和方法的访问控制
前面我们多次提到过对类, 变量及方法的访问控
制属性, 比如有,private,friendly,protected及 public。
Java中最低访问控制范围是类的级别, 与之对应也分
为四种:同一个类, 同一个包, 不同包的子类及不同
包的非子类 。
表 6.1给出了每一种访问指示的访问等级 。
第 6章 Java中类, 对象, 接口及包的概念
表 6.1 访问控制权限表
访问指示 类 子类 包 所有
private √
protected √ √ √
public √ √ √ √
friendly √ √
第 6章 Java中类, 对象, 接口及包的概念
表 6.1中, 第二列给出了是否类本身可以访问它的
成员 (从上表可以知道, 类总是可以访问它自己的成员 );
第三列给出了是否类的子类可以访问它的成员;第四
列给出了是否在相同包中的类可以访问该类成员;第
五列给出了是否所有的类可以访问该类成员 。
类的访问控制权限只能为 public和 friendly,变量和
方法的访问控制可以为上面四种的任何一种 。
第 6章 Java中类, 对象, 接口及包的概念
● private
private成员只能被它所定义的类或类的不同对象
所访问 。 外部访问这个变量就会出错, 因为如果
private的方法被外部类调用, 就会使得程序或对象处
于不安全状态 。 private成员就像不能告诉任何人的秘
密, 所以, 任何不需要他人直接访问的成员都应该定
义为 private类型 。
下面的类 A包含了一个 private成员变量和一个
private方法:
第 6章 Java中类, 对象, 接口及包的概念
class A {
private int private Variable;
private void private Method() {
System.out.println("Test for private definition!");} }
在做了以上的定义之后, A类型的对象可以调用
或者修改 private Variable变量以及调用 private Method方
法, 但是其他类型的对象却不行 。 比如, 以下的类 B就
不能访问 private Variable变量或者调用 private Method方
法, 因为类 B不是 A类型的 。
class B {
void access Method() {
第 6章 Java中类, 对象, 接口及包的概念
A a = new A ();
a,privateVariable = 10; //非法
a.privateMethod(); //非法
}}
这时, 编译器就会给出以下错误信息并拒绝继续编译程
序:
B.java:9,Variable privateVariable in class A not accessible
from class B.
//在类 A中的 privateVariable变量不能从类 B中进行访问
a,privateVariable = 10; // 非法
^
1 error //程序中有一个错误
第 6章 Java中类, 对象, 接口及包的概念
与此类似, 如果程序试图访问方法 privateMethod()时, 将
导致如下的编译错误:
B.java:12,No method matching privateMethod()
found in class A,//在类 A中没有匹配的方法
privateMethod()
a.privateMethod(); // 非法
1 error //一个错误
下面我们再给出一个例子来解释同类对象调用
private的方法 。 假如 A类包含了一个实例方法, 它用于
比 较 当 前 的 A 对象 (this) 同 另 外 一 个 对 象 的
privateVariable变量是否相等:
class A {
第 6章 Java中类, 对象, 接口及包的概念
private int private Variable;
boolean is Equal To(A anotherA) {
if (this,Private Variable == another A,private Variable)
return true;
else
return false;}
}
结果是运行正常 。 可见, 相同类型的对象可以访
问其他对象的 private成员 。 这是因为访问限制只是在类
别层次 (类的所有实例 )而不是在对象层次 (类的特定实
例 )上 。
第 6章 Java中类, 对象, 接口及包的概念
实际应用过程中, 如果我们不想让别的类生成自
己定义的类的实例, 可以将其构造方法声明为 private类
型 。 比如, java.lang.System,它的构造方法为 private,
所以不能被实例化, 但由于其所有方法和变量均定义
为 static类型, 故可以直接调用其方法和变量 。
第 6章 Java中类, 对象, 接口及包的概念
● protected
定义为 protected的类成员允许类本身, 子类以及
在相同包中的类访问它 。 一般来说, 需要子类访问的
成员, 可以使用 protected进行限制 。 protected成员就像
家庭秘密, 家里人知道无所谓, 但是却不让外人知道 。
现在我们看看 protected是怎样限制使用在相同包内的类
的 。 假如上面的那个类 A现在被定义在一个包 Protect1
内, 它有一个 protected成员变量和一个 protected方法,
具体如下:
第 6章 Java中类, 对象, 接口及包的概念
package Protext1;
public class A {
protected int protectVariable;
protected void protectMethod() {
System.out.println("Test for protected definition!");}}
现在,假设类 C也声明为 Protect1包的一个成员 (不
是 A的子类 )。则类 C可以合法地访问 A对象的 protect
Variable成员变量并且可以合法调用它的 protect Method,
如下,package Protect1;
第 6章 Java中类, 对象, 接口及包的概念
class C {
void access Method() {
A a = new A ();
a,protect Variable = 10; //合法
a.protect Method(); //合法
}}
下面我们探讨 protected如何限制类 A子类的访问。
首先定义类 D,它由类 A继承而来,但处在不同的包中,
设为 Protect2。则类 D可以访问其本身类实例成员
protect Variable和 protect Method,但不能访问类 A对象
中的 protect Variable或者 protect Method。
第 6章 Java中类, 对象, 接口及包的概念
在下面代码中, access Method试图访问在 A类型对
象中的 protect Variable成员变量, 这是不合法的, 而访
问 D类型对象则是合法的 。 与此相同, access Method
试图调用 A对象的 protect Method方法也是非法的 。 见
下例:
package Protect2;
import Protect1.*;
class D extends A {
void access Method(A a,D d) {
a,protect Variable = 10; //非法
第 6章 Java中类, 对象, 接口及包的概念
d,protect Variable = 10; //合法
a.protect Method(); //非法
d.protect Method(); //合法
}}
● public
public是 Java中最简单的访问控制符 。 修饰为 public
的成员在任何类中, 任何包中都可以访问, 它相当于
是无任何秘密可言, 从其使用角度来看, 有点相当于 C
语言中的外部变量 。 例如:
第 6章 Java中类, 对象, 接口及包的概念
package Public1;
public class A {
public int public Variable;
public void public Method() {
System.out.println("Test for public definition!");}}
接下来, 我们重新编写类 B,将它放置到不同的包中, 并
且让它跟类 A毫无关系:
package Public2;
import Public1.*;
class B {
void access Method() {
第 6章 Java中类, 对象, 接口及包的概念
A a = new A ();
a,public Variable = 10; // 合法
a.public Method(); // 合法
}}
从上面的代码段我们可以看出,这时类 B可以合
法地使用和修改在类 A中的 public Variable变量及方法
public Method。
第 6章 Java中类, 对象, 接口及包的概念
● friendly
friendly关键字我们并不陌生, 在 C++中其表示友
元类, Java中如果不显式设置成员访问控制的时候 (即
缺省的访问控制 ),则隐含使用 friendly访问控制 。 该访
问控制允许在相同包中的类成员之间相互可以访问 。
就像在相同包中的类是互相信任的朋友 。 下例中, 类 A
声明了一个单一包访问的成员变量和方法 。 它处在
Friend包中:
第 6章 Java中类, 对象, 接口及包的概念
package Friend;
class A {
int friend Variable; //缺省为 friendly
void friend Method() //缺省为 friendly
{System.out.println("Test for friendly definition!");}
}
这样,所有定义在和类 A相同的包中的类也可以访问
friend Variable和 friend Method。
第 6章 Java中类, 对象, 接口及包的概念
假如 A和 B都被定义为 Friend包的一部分, 则如下的
代码是合法的:
package Greek;
class B {
void access Method() {
A a = new A ();
a,friend Variable = 10; //合法
a.friend Method(); //合法
}
}
第 6章 Java中类, 对象, 接口及包的概念
6.2 对 象
6.2.1 对象的创建
Java中创建新的对象必须使用 new语句,其一般格
式为 class Name object Name = new class
Name( parameter List);此表达式隐含了三个部分,即:
对象说明、实例化和初始化。
第 6章 Java中类, 对象, 接口及包的概念
● 对象说明:上面的声明格式中,class Name
object Name是对象的说明; class Name是某个类名,用
来说明对象所属的类; object Name为对象名。例如:
Integer I Variable;该语句说明 I Variable为 Integer类型。
● 实例化,new是 Java实例化对象的运算符 。 使用
命令 new可以创建新的对象并且为对象分配内存空间 。
一旦初始化, 所有的实例变量也将被初始化, 即算术
类型初始化为 0,布尔逻辑型初始化为 false,复合类型
初始化为 null。 例如:
Integer I Variable = new Integer (100);
此句实现将 Integer类型的对象 I Variable初始值设
为 100的功能 。
第 6章 Java中类, 对象, 接口及包的概念
● 初始化,new运算符后紧跟着一个构造方法的
调用 。 前面我们介绍过, Java中构造方法可以重构,
因而通过给出不同的参数类型或个数就可以进行不同
初始化工作 。 如例 6.3,类 Rectangle定义了一个矩形类,
它有多个不同的构造方法, 我们可以通过调用不同的
构造方法来进行初始化 。
第 6章 Java中类, 对象, 接口及包的概念
例 6.3
public class Rectangle {
public int width = 0;
public int height = 0;
public Point origin;
public static void main(String args[]){
Point p=new Point(20,20);
Rectangle r1=new Rectangle();
Rectangle r2=new Rectangle(p,80,40);
第 6章 Java中类, 对象, 接口及包的概念
Transcript.println("The area of Rectangle1 is,"+r1.area());
Transcript.println("The area of Rectangle1 is,"+r2.area()); }
public Rectangle() {
origin = new Point(0,0);}
public Rectangle(Point p) {
origin = p;}
public Rectangle(int w,int h) {
this(new Point(0,0),w,h);}
public Rectangle(Point p,int w,int h) {
origin = p; width = w; height = h;}
public void move(int x,int y) {
第 6章 Java中类, 对象, 接口及包的概念
origin.x = x;
origin.y = y;}
public int area() {
return width * height;}
}
public class Point {
public int x = 0;
public int y = 0;
第 6章 Java中类, 对象, 接口及包的概念
图 6.4
第 6章 Java中类, 对象, 接口及包的概念
public Point(int x,int y) {
this.x = x; this.y = y;}
}
该例中, 我们定义了两个类 Rectangle,Point,并
调用了类 Rectangle中的 area()方法来求矩形的面积 。 方
法 Rectangle()不带参数, 因而只是初始化原点坐标为
(0,0),矩形的长, 宽各为 0;方法 Rectangle(p,80,40)不
仅初始化原点由类型 Point()指定, 同时还限定矩形的
长, 宽各为 80,40。 此程序的运行结果如图 6.4所示 。
第 6章 Java中类, 对象, 接口及包的概念
6.2.2 对象的使用
前面我们花了很大的篇幅介绍类, 其目的就是为
了掌握如何使用它 。 类是通过实例化为对象来使用的,
而对象的使用是通过引用对象变量或调用对象的方法
来实现的 。 与 C++相类似, 对象变量和方法均是通过
运算符,,”来实现的 。
1,变量的引用
对象变量引用的一般格式为
object Name.variable Name
第 6章 Java中类, 对象, 接口及包的概念
例如:
class example {
int x; }
example a = new example();
a.x=100;
变量的引用在 Java中还有一种很特殊的情况, 即可
以使用表达式指定变量所在的对象, 例如:
int z= new example().x;
第 6章 Java中类, 对象, 接口及包的概念
这个语句创建了一个新的 example对象, 并且得到
了它的成员变量 x。 需要注意的是, 在这条语句被执行
后, 程序不再保留对象 example的引用 。 这样, 对象
example就被取消引用, 因而通过上述语句并不能达到
初始化对象的作用 。
第 6章 Java中类, 对象, 接口及包的概念
2,对象方法的引用
与对象变量引用一样, 对象方法的引用一般格式为
object Name.method Name([argument List]);
例如我们在例 6.3中调用对象 Rectangle中的 area()方
法计算矩形的面积:
Transcript.println("The area of Rectangle1 is,"+r1.area());
Transcript.println("The area of Rectangle1 is,"+r2.area());
第 6章 Java中类, 对象, 接口及包的概念
虽然通过直接引用对象变量可以改变对象的属性,
但是它没有任何意义 (比如,我们在例 6.3中,使用
Rectangle类的构造方法,可以创建不同的矩形,如果设
置其高 height、宽 width是负的,程序并不认为其非法 )。
所以,较好的做法是:不直接对变量进行操作,而由类
提供一些方法,对变量的引用可以通过这些方法来进行,
以确保给定变量的数值是有意义的。这样一来,
Rectangle类将提供 setWidth,setHeight,getWidth以及
getHeight方法来设置或者获得宽度和高度。设置变量的
方法将在调用者试图将 width和 height设置为负数的时候
给出一个错误。这样能够更好地体现数据的封装和隐蔽。
例如,加上上述的几个方法后,例 6.3变为
第 6章 Java中类, 对象, 接口及包的概念
public class Rectangle
{
...
public void setWidth(int width) {
if (width < 0)
System.out.println("Illegal number! ");
else
this.width=width; }
public void setHeight(int height) {
...}
第 6章 Java中类, 对象, 接口及包的概念
public int getWidth() {
return width; }
public int getHeight(){
return height;}
public void move(int x,int y) {
origin.x = x; origin.y = y; }
public int area() {
return width * height;
}
}
第 6章 Java中类, 对象, 接口及包的概念
6.3 类的继承概念
Java通过子类实现继承 。 继承指的是某个对象所
属的类在层次结构中占一定的位置, 具有上一层次对
象的某些属性 。 在 Java中, 所有的类都是通过直接或
间接地继承 java.lang.Object类得到的, 如图 6.5所示 。
第 6章 Java中类, 对象, 接口及包的概念
图 6.5
第 6章 Java中类, 对象, 接口及包的概念
在类的继承过程中, 被继承的类为父类或超类,
继承得到的类为子类 。 父类包括所有直接或间接被继
承的类 。 子类继承父类的状态和行为, 也可以修改父
类的状态或重写父类的行为 (方法 ),同时也可以再添加
新的状态和行为 (方法 )。 需要注意的是, Java与 C++不
同, 不支持多重继承 。 同时, 为了使继承更为灵活和
完善, Java支持最终类和抽象类的概念 。
第 6章 Java中类, 对象, 接口及包的概念
所谓的最终类, 同数结构中的树叶节点一样, 就
是不允许对它进行扩展的类, 也就是说不可以有该类
的子类 。 实际使用过程中, 可以在定义类时用关键字
final对它加以说明 。 引入最终类的好处是为了提高系
统安全性, 因为如果有重要的信息的类允许继承的话,
就可能被不怀好意的攻击者加以利用, 从而重要的数
据就可能被非法修改或泄密 。 为了防止这些情况发生,
可以将那些重要的类说明为最终类, 避免非安全事件
的发生 。
第 6章 Java中类, 对象, 接口及包的概念
Java中, 类层次的另一个概念就是抽象类, 它与最
终类相对, 需要子类继承完善 。 在类的说明中我们已
讨论过, 这里不再详细说明, 只是有几点注意事项希
望读者留意:
(1) 构造方法不能定义为抽象方法 。
(2) 最终方法不能说明为抽象方法 。
(3) static和 private修饰符不能用于抽象方法 。
(4) 不能重载父类中的抽象方法 。
第 6章 Java中类, 对象, 接口及包的概念
6.3.1 子类的创建
通过关键字 extends来创建某个类的子类, 其语法如下:
class subclass Name extends superclass Name {...}
例如:
class Rectangle extends Shape {...}
这样, 类 Rectangle就可以继承父类 Shape中的成员
变量和方法 。 前面一些例子中, 在作类的定义时, 并
没有指明继承于某个父类, 比如:
public class Rectangle {,.,}
第 6章 Java中类, 对象, 接口及包的概念
此时, 隐含认为类 Rectangle缺省继承于类 Object。
当然, 继承父类中的 private属性的变量和方法也是受限
制的, 这是大家需要注意的地方 。 我们可以发现, 通
过继承的关系, 使得成熟的代码可以获得重用的好处,
大大提高了编程的效率 。 同时, 由类封装而带来的数
据隐藏, 也可以提高程序的可维护性 。
第 6章 Java中类, 对象, 接口及包的概念
6.3.2 变量的隐藏
继承给我们带来方便, 但如果使用中概念不清,
也可能会给我们带来一些问题 。 假设我们实现了某个
类的继承, 当子类中的成员变量与父类中的成员变量
同名时, 应该怎么办呢? Java解决这一问题的办法是
采用所谓的变量隐藏机制 。 也就是说, 如果该种情况
发生, 则父类中的变量将被隐藏起来 。 例如:
class super Class {
int same Variable;
...}
第 6章 Java中类, 对象, 接口及包的概念
class sub Class extends super Class{
int same Variable
// 此时, 此处变量 same Variable隐藏了父类的同
名变量
...}
可能有的读者会说,那我非要用父类中的同名变
量,应该怎么办呢?其实我们前面讨论构造方法时已
经提到过:当引用父类中的变量时,必须使用 super关
键字。
第 6章 Java中类, 对象, 接口及包的概念
class sub Class extends super Class{
int same Variable
//此时, 此处变量 same Variable隐藏了父类的同名变量
...
System.out.println( "Now output the Super Class variable!
" + super.sameVariable);
//引用父类中的变量
}
第 6章 Java中类, 对象, 接口及包的概念
6.3.3 方法置换
与我们前面所介绍的方法重载很相似, Java中的方
法置换指的是子类中的方法名与父类中的某个方法名
相同, 此时, 子类中的同名方法就被称为置换方法 。
置换方法与父类中的同名方法具有相同的方法名, 相
同的返回值类型和相同的参数表 。 如果要调用父类中
的同名方法, 也使用关键字 super进行前缀修饰 。 例如:
第 6章 Java中类, 对象, 接口及包的概念
例 6.4
package untitled4;
import genesis.*;
public class MyClass1 {
int x,y;
public MyClass1(){ }
public MyClass1(int x,int y) {
this.x=x; this.y=y; }
public void test(){
Transcript.println("x,y in superclass is,"+x+" "+y);}
第 6章 Java中类, 对象, 接口及包的概念
}
package untitled4;
import genesis.*;
public class MyClass2 extends MyClass1 {
int x,y;
public MyClass2(int x,int y) {
this.x=x;
this.y=y; }
public static void main(String args[]){
MyClass2 m2= new MyClass2(10,20);
MyClass1 m1=m2;
m1.test(); m2.test();}
第 6章 Java中类, 对象, 接口及包的概念
public void test(){
super.test();
Transcript.println("x,y in subclass is,"+ x+" "+y);
}}
运行结果如图 6.6所示 。 请读者仔细分析程序的执行结果 。
第 6章 Java中类, 对象, 接口及包的概念
图 6.6
第 6章 Java中类, 对象, 接口及包的概念
6.4 Java中接口与包的概念
在上一小节我们讨论了 Java中的一个重要特征:继
承机制 。 由于 Java只支持单一继承, 即一个子类只有
一个父类 (与 C++不同 ),但实际的开发过程中, 可能会
碰到需要多重继承的情况, 这应该怎么办呢? Java中
的接口机制为我们提供了实现多重继承的可能 。 接口
的概念较 C++中的多重继承概念要简单, 方便, 它可
以达到多个不相关的类具有相同的方法这一特殊效果 。
第 6章 Java中类, 对象, 接口及包的概念
6.4.1 接口
接口是一系列没有实现的方法和常量的组合, 它
提供方法协议的封装, 但不限制子类如何实现这些方
法, 从而使得类的继承变得简单而灵活 。 通过接口我
们可以使处于不同层次, 互不相干的类具有相同的行
为 。 总的来说, 接口的功能可以归纳为如下几点:
第 6章 Java中类, 对象, 接口及包的概念
(1) 通过接口可以实现不相干类的相同行为而不需
考虑这些类之间的层次关系 。
(2) 通过接口可以指明多个类需要实现的方法 。
(3) 通过接口可以了解对象的交互界面而不需了解
对象所对应的类 。
Java中的接口的基本组成如图 6.7所示 。
第 6章 Java中类, 对象, 接口及包的概念
public interface inter face Name {
final String name="Name";
final String sex="male";
...
void aInter face Example(parameter List);
}
第 6章 Java中类, 对象, 接口及包的概念
图 6.7
public interface interfaceName {
final String name="Name";
final String sex="male";
…
void aInterfaceExample(parameterList);
}
接口声明
接口体
常量定义
方法声明
第 6章 Java中类, 对象, 接口及包的概念
图 6.7给出了一个接口的常见声明格式 。 接口声明
定义了各种关于接口的属性, 如它的名字和是否扩展
其他的属性等;接口实体包含了常数和用于接口的方
法声明 。
1,接口的声明
与类的声明格式相似, 接口的声明格式如下:
Modifiers interface inter face Name
[extends superinter face_List]
{inter face Body}
第 6章 Java中类, 对象, 接口及包的概念
在接口定义中, 必须有两个元素,interface关键字
和接口的名字, 其他均为可选项 。 如果访问限制为
public,则表示接口可以在任何包的任何类中使用 。 如
果没有指定接口为 public,那么接口就只能在定义接口
的包的类中使用了 。 接口隐含修饰符为 abstract,当然,
也可以显式指明为 abstract,但是没有必要 。
第 6章 Java中类, 对象, 接口及包的概念
接口定义可以有另外一个选项,superinter
face_List系列。一个接口可以通过关键字 extends扩展另
外的接口,这跟类可以扩展的概念一样。但是,类只
能扩展一个另外的类,而接口可以扩展任意多个接口。
Superinter face_List系列以逗号 (,)分隔的所有接口,
这些接口可以由新的接口扩展。我们知道,在类的扩
展中,所有的类,其超类均为 Object,而接口没有所谓
的超接口。
接口实体为所有包含在接口中的方法及变量 。
第 6章 Java中类, 对象, 接口及包的概念
所有定义在接口中的方法隐含为 public和 abstact。
所有定义在接口中的常量可以是 public,static和
final,接口中的变量隐含为静态变量 (static)。 定义在接
口中的成员声明不允许使用某些声明修饰语, 比如不
能在接口中的成员声明中使用 transient,volatile或者
synchronized。 同样, 不能在声明接口成员的时候使用
private和 protected修饰语 。
第 6章 Java中类, 对象, 接口及包的概念
另外一点需要注意的是, 接口中的方法不能有方法体,
所以实现接口的类必须实现接口中的所有方法 。 例如:
public interface My inter face extends superinter face{
String name;
final int x=10;
void My method(int x,int y);
...}
第 6章 Java中类, 对象, 接口及包的概念
2,接口的实现
Java中提供接口的目的当然是为了使用它,用户
定义的类要使用某个接口时,必须首先实现这一接口。
可以通过关键字 implements说明该类要实现的一个或多
个接口,之后在类体中完成接口所有方法的代码。如
此才能使用被实现了的方法。实际使用中,可能会碰
到实现接口的类是抽象类,这样,完善接口方法的任
务就必须由该类的子类来完成。
例如:
第 6章 Java中类, 对象, 接口及包的概念
public class inter face Example implements Runnable{
Thread my Thread;
...
public void run(){
..,//实现接口中的
Runnable方法
}
...}
第 6章 Java中类, 对象, 接口及包的概念
当定义一个新的接口时,从本质上讲,就好像定
义了一个新的引用数据类型。可以在使用其他类型的
名字 (比如变量声明、方法参数等等 )的地方,使用接口
名字。这样我们就可以不必知道对象的精确类型,只
需知道接口的行为,增加了程序的方便性。例如:
public class My class implements On einter face {
...
void doMethod(int x) {
..,//实现接口中的某方法
}
...}
第 6章 Java中类, 对象, 接口及包的概念
public class Useinter face As Para {
int x;
My class m=new My class();
...
void passinter faceAsPara(On einter face m) {
m.do Method(x);
}
...}
第 6章 Java中类, 对象, 接口及包的概念
6.4.2 包 (package)的基本概念
为了使得类更容易地被发现和使用,以及避免名字
空间的冲突、控制访问,Java不支持全局变量和全局
方法,程序员要捆绑相关的类和接口到包中,所有变
量和方法都是在类中定义,而每个类又是包的一部分。
变量和方法都可以用全限定的名字表示,该表示方法
包括包名、类名和类成员名三个组成部分,各部分之
间用,.”符号分隔开,同时包本身也可以用该分隔符组
成的域指明。
第 6章 Java中类, 对象, 接口及包的概念
例如:基本类是在 java.lang中, 而用于阅读和书写
的类在 java.io中等等 。 我们也可以放置自己的类和接口
到某个包中 。 比如在例 6.4中, 首行语句为
package untitled4;
由于我们在 JBuilder3中进行属性设置时把根目录源
路径设置为
c:\JBuilder3\myprojects;
则语句, package untitled4;”表达的意思就是该包
所处的位置为
c:\JBuilder3\myprojects\untitled4
第 6章 Java中类, 对象, 接口及包的概念
这样, 当我们对类 Myclass1及 Myclass2进行编译后,
得到的两个字节码文件 Myclass1.class,Myclass2.class
均在此目录下 。 所以, 包名实际上是,class文件的绝对
路径 。 如果我们使用的是 JDK,则路径的说明必须由
环境变量 CLASSPATH进行定义 。
1,包的定义
我们知道, Java中的包与 C/C++中的 #include语句
及 Pascal语言中的 Unit语句相类似, package语句的一般
形式为
package package Name;
第 6章 Java中类, 对象, 接口及包的概念
我们常常把自己设计的类或接口组成一个或多个
包, 使得功能相近, 用途相同, 关系密切的类和接口
纳入一个包中 。 从前面我们介绍的访问控制属性中大
家知道, 同一个包中的类或接口相互之间的访问权限
要高于与它们不在同一个包中的类或接口 。 这样, 当
我们设计类的时候只要划分好包的层次, 就可以使处
于包中的类或接口的功能与本类提供的功能相协调 。
例如在例 6.4中, 类 MyClass1及类 MyClass2二者开头的
一条语句均为
package untitled4;
第 6章 Java中类, 对象, 接口及包的概念
表明二者处在同一个包中,之后经编译所形成
的,class也是处在同一个目录下。这样才能充分利用包
机制所提供的类组织以及由此而带来的更为灵活方便
的代码重用。
2,包的引入
一般来说,java.lang包中定义了基本的类和接口,
当编译的时候,Java编译器会自动将所需要的内容引
入。如果要引入用户自定义的包,可以使用 import语句
引入。该语句的功能是引入包或包中的类,从而使得
当前类可以用省略的形式来使用包中的类或接口。
第 6章 Java中类, 对象, 接口及包的概念
有:
① import package Name;
② import package Name.class;
③ import package.*;
这三种格式大致相同, 但存在一些细微的区别 。
第一种格式允许只用包名中的最后一部分来指定包名,
例如:
import java.lang.String;
第 6章 Java中类, 对象, 接口及包的概念
这样, 今后就可以直接使用包中 String类的变量和
方法 (如果最后项所指为类 ),当最后项为包时, 则可以
直接使用对应包中的类及方法 。 第二种格式与第一种
相似, 只是所指为确定的某一类 。 第三种格式最常用,
其功能为使包中的所有类都可以用其类名直接访问,
例如:
import java.lang.*;
第 6章 Java中类, 对象, 接口及包的概念
与 C/C++类似, import 语句在程序中也可以有任意
多个, 只是必须清楚引入的包中是否有本人需要的类,
例如:
import java.awt.*;
import java.net.*;
第 6章 Java中类, 对象, 接口及包的概念
3,Java中的常用包
C中的头文件 io.h,string.h是比较常用的,与此相
同,Java也有一些编程中常用的包、类和接口。例如
字符串处理、网络开发、窗口调用、数学计算及异常
处理等等。这里,为了更好的理解,我们给出 Java中
常用的包,它与 Windows一样,集成为一个应用程序
借口 API(Application Programming Interface),如表 6.2
所示
第 6章 Java中类, 对象, 接口及包的概念
表 6.2 常用包列表
包 名 功 能 描 述
java.applet 使用 Applet的类和接口
java.awt Java抽象窗口工具集
java.awt.image 图像处理类
java.awt.peer 使 Java的窗口系统跨平台移植的类和接口
java.io 输入 /输出类和接口
java.lang Java的核心类, 包括字符串, 数学计算, 异常处理等
java.net 网络应用类和接口
java.util 优化程序设计的一些类, 如矢量队列等
javax.swing 扩展的一些 Java类和接口