2.2 类和对象
2.2.1 类的声明
类是java中的一种重要的复合数据类型,是组成java程序的基本要素。它封装了一类对象的状态和方法,是这一类对象的原形。一个类的实现包括两个部分:类声明和类体。
如:宠物类的狗(Dog),是一个客观存在的对象,在Java中将它的特性抽象出来,形成一个类。
public class Dog {
String name ; // 昵称
String color; //颜色
String strain; // 品种
public void bark() {
System.out.println("我的名字是"+name+",我是一条"+color+"色的"+strain);
}
}
Dog类中定义了三个成员name、color、和strain,用于表示狗的昵称、颜色和品种,还定义了一个行为(方法)。
如:坐标中一个点(x,y),是一个客观存在的对象。在Java中将它的特性抽象出来,形成一个类。
class Point{
int x;
int y;
void setPoint(int ox, int oy){x=ox; y=oy;}
……
}
Point类中定义了两个数据成员x和y,用于表示点对象的x坐标和y坐标,还定义了一系列方法用于对点对象进行操作。
1.类声明:
[public][abstract|final] class className [extends superclassName] [implements interfaceNameList] {
<类体>
}
其中,修饰符public,abstract,final 说明了类的属性,className为类名, superclassName为类的父类的名字,interfaceNameList为类所实现的接口列表。
类名是Java合法的标识符名,按Java编码规定,类名的英文单词的第一个字母要大写,若由多个单词组成,则每一个单词的首字母都要大写。
2.类体
类体定义如下:
class className{
[public | protected | private ] [static] [final] [transient] [volatile]
type variableName;//成员变量
[public | protected | private ] [static][final | abstract] [native] [synchronized]
returnType methodName([paramList]) [throws exceptionList] {
statements
} //成员方法
}
【例】钟表(Clock)类举例。
public class Clock {
//成员变量
int hour;
int minute;
int second;
//成员方法
public void setTime(int newH,int newM,int newS){
hour=newH;
minute=newM;
second=newS;
}
public void showTime(){
System.out.println(hour+":"+minute+":"+second);
}
}
2.2.2对象
类的一个对象就称为类的一个实例(instance)。一个实例是一个类的特定个体,它具有区别于其他实例的状态。
1.对象的声明
对象声明的一般格式为:
type objectName;
声明并不为对象分配内存空间,而只是分配一个引用(reference)空间;对象的引用类似于指针,是32位的地址空间,它的值指向一个中间的数据结构,它存储有关数据类型的信息以及当前对象所在的堆的地址,而对于对象所在的实际的内存地址是不可操作的,这就保证了安全性。
如:
Clock aClock;
Dog myDog,yourDog;
2.对象实例化
使用new运算符和类的构造方法为声明的对象分配内存,如果类中没有构造方法,系统会调用默认的构造方法(构造方法在后面详细解释),返回引用;一个类的不同对象分别占据不同的内存空间。
如:
aClock=new Clock( );
myDog=new Dog( );
如果在程序中使用了下述赋值语句:
yourDog=myDog;
把myDog的引用(myDog在内存中的名字)赋给了yourDog,因此,myDog和yourDog本质上是一样的,即myDog和yourDog有相同的实体。内存模式如图2.2所示。
要注意,声明一个引用变量时并没有对象生成,例如,下面的语句在编译时会产生错误信息“The local variable clock may not have been initialized”(变量clock没有被初始化)。
Clock clock;
System.out.println(clock);
3. 对象对成员变量的使用
通过运算符"."可以实现对成员变量的访问和成员方法的调用。成员变量和成员方法可以通过设定访问权限来限制其它对象对它的访问。
成员变量的声明方式如下:
[public | protected | private ] [static] [final] [transient] [volatile] type variableName;
其中,
[public | protected | private ]为访问控制符;
static: 指明这是一个静态变量(类变量);//相对于实例变量
final: 指明常量的值不能被修改;
transient: 指明变量表示一个暂时性变量,用于对象存档;
volatile: 指明变量是一个共享变量,用于并发线程的共享。
type: 成员变量的类型可以是Java中的任意的数据类型,包括简单类型、类、接口和数组。在一个类中的成员变量应该是唯一的。
用来存储所有实例都需要的属性信息,不同实例的属性值可能会不同。访问实例属性值的格式如下:
<实例名>.<实例变量>
【】Point类的测试类
public class TestPoint {
public static void main(String[] args) {
Point a,b;
a = new Point();
System.out.println(a);
System.out.println("x = "+a.x);
b = new Point();
b.x = 2;
b.y = 3;
}
}
编译后的运行结果如下:
Point@c17164
x = 0
其中@之后的数值为a所指的变量的存储地址.
4. 对象对成员方法的使用
成员方法的实现包括两部分内容:方法声明和方法体。
[public | protected | private ] [static][final| abstract] [native] [synchronized]
returnType methodName([paramList])[throws exceptionList]//方法声明
{statements} //方法体
方法声明中的限定词的含义:
static: 类方法,可通过类名直接调用
abstract: 抽象方法,没有方法体
final: 方法不能被重写
native: 集成其它语言的代码
synchronized: 控制多个并发线程的访问
returnType: 方法的返回值类型,返回类型可以是任意的Java数据类型,当一个方法不需要返回值时,返回类型为void;
paramList: 参数的类型,可以是简单数据类型,也可以是复合数据类型(又称引用数据类型)。
方法体是对方法的实现。它包括局部变量的声明及所有合法的Java指令。局部变量的作用域只在方法内部。
throws exceptionList: 用来处理异常。
为了理解对象的行为,可以将对象看成活的实体(living entities),想与对象交流或操纵一个对象时,需要给对象发一条消息(message)。给对象发消息即意味着调用对象的某个方法。发送消息的格式如下:
<对象名>.<方法名>([参数列表])
<对象名>是消息的接受者(receiver)。
方法定义了当一条消息发送给对象时需要执行的功能,通常有以下三条:
◇ 从接收者对象中取得信息;
◇ 以某种方式修改对象的状态或进行某种操作;
◇ 进行计算及取得结果等。
一个方法可以有多个参数,对于简单数据类型来说,java实现的是值传递,方法接收参数的值,但不能改变这些参数的值。如果要改变参数的值,则用引用数据类型,因为引用数据类型传递给方法的是数据在内存中的地址,方法中对数据的操作可以改变数据的值。
实例方法表示特定对象的行为,在声明时不加static修饰符,在使用时需要发送给一个类实例。
【例】Clock测试类
public class TestClock {
public static void main(String[] args){
Clock aClock;
aClock = new Clock();
aClock.setTime(1, 20, 35);
aClock.showTime();
aClock.hour=10;
aClock.showTime();
}
}
运行结果如下:
1:20:35
10:20:35
在上例中,使用实例方法setTime()和showTime()时,需要将其发送给一个实例对象aClock,执行aClock.setTime(1, 20, 35)时,hour、minute、second的值为aClock的三个属性值,执行aClock.showTime()时,hour、minute、second的值仍为aClock的三个属性值。