对象

对象

出了这个类的一个实例.

创建对象

创建一个对象包括对象的声明和为对象分配内存两个步骤.

1 对象的声明.

 一般格式为 类的名字  对象名字;

People zhangPing

这里 People 是一个类的名字,zhangPing 是我们声明的对象的名字.

2 为声明的对象分配内存.

使用 new 运算符和类的构造方法为声明的对象分配内存,如果类中没有构造方法,系统 会调用默认的构造方法 默认的构造方法是无参数的,你一定还记得构造方法的名字必须和 类名相同这一规定 .如

zhangPing=new People();

以下是两个详细的例子.

例子 1

class XiyoujiRenwu

{ float height,weight;

String head, ear,hand,foot, mouth;

void speak(String s)

{  System.out.println(s);

}

}

class A{ public static void main(String args[])

{ XiyoujiRenwu  zhubajie; //声明对象.

zhubajie=new  XiyoujiRenwu(); //为对象分配内存,使用 new 运算符和默认的构造方法.

…    …  . …  .

}

}

例子 2

class Point

{ int x,y;

Point(int a,int b)

{ x=a;

y=b;

}

}

public class A

{ public static void main(String args[])

{ Point p1,p2; //声明对象 p1 和 p2.

p1=new Point(10,10); //为对象分配内存,使用 new 和类中的构造方法. p2=new Point(23,35); //为对象分配内存,使用 new 和类中的构造方法.

}

}

如果你的类里定义了一个或多个构造方法,那么 Java 不提供默认的构造方法.

上述例子 2 提供了构造方法,下列创建对象是非法的

p1=new Point();

3 对象的内存模型

我们使用前面的例子 1 来说明对象的内存模型.

1 声明对象时的内存模型.

当用 XiyoujiRenwu 类声明一个变量 zhubajie,即对象

zhubajie 时,如例子 1 中

XiyoujiRenwu  zhubajie;

内存模型如图 4.1 所示.

zhubajie

 4.1    对象

声明对象变量 zhubajie 后,zhubajie 的内存中还没有任何数据, 我们称这时的

zhubajie 是一个空对象,空对象不能使用,因为它还没有得到任何”实体”.必须再进行为对 象分配内存的步骤,即为对象分配实体.

2 对象分配内存后的内存模型

当系统见到

zhubajie=new XiyoujiRenwu();

时,就会做两件事

为  height,weight,head,ear,mouth,hand,foot  各 个 变 量 分配 内 存 . 即 XiyoujiRenwu 类的成员变量被分配内存空间.如果成员变量在声明时没有指定初值,那么, 对于整型变量,默认初值是 0 对于浮点型,默认初值是 0.0 对于 booean 型,默认初值是 false 对于引用型,默认初值是 null.

给出一个信息,已确保这些变量是属于对象 zhubajie 的,即这些内存单元将由 zhubajie 操 作 管 理 . 为 了 作 到 这 一 点 ,new 运 算 符 在 为 变 量 height,weight,head,ear,mouth,hand,foot 分配内存 后 , 将返回一个引用给对象变量 zhubajie.也就是返回一个”号码” 地址号,即代表这些成员变量内存位置的首地址号码

给 zhubajie,你不妨就认为这个引用就是 zhubajie 在内存里的名字,而且这个名字 引用

是 Java 系统确保分配给 height,weight,head,ear,mouth,hand,foot 的内存单元将由 zhubajie 操作管理.称 height,weight,head,ear,mouth,hand,foot 分配的内存单元是属 于对象 zhubajie 的实体,即这些变量是属于 zhubajie 的.所谓为对象分配内存就是指为它 分配变量,并获得一个引用,以确保这些变量由它来”操作管理”.为对象分配内存后,内存模 型由声明对象时的模型 图 4.1,变成如图 4.2 所示意.

zhubajie

0xAB12

 4.2   对象

weight

height

head ear mouth hand foo

如果你的想象力丰富的话,那么你可以想象在这个计算机内存中的”现实世界”里就有了一个”活

zhubajie. zhubajie 的 height,weight,head,ear,mouth,hand,foot 进行操作,改变自己的状态,高兴的话就改变 成一个浓眉大眼的壮汉,到高老庄去.

对象的声明和分配内存两个步骤可以用一个等价的步骤完成,如

XiyoujiRenwu zhubajie=new XiyoujiRenwu();

3 创建多个不同的对象

一个类通过使用 new 运算符可以创建多个不同的对象,这些对象将被分配不同的内存空

间,因此,改变其中一个对象的状态不会影响其它对象的状态.例如,我们可以在上述例子 1

中创建两个对象 zhubajie,sunwukong.

zhubajie=new XiyoujiRenwu();

sunwukong =new XiyoujiRenwu();

当  创  建  对  象 zhubajie 时  ,XiyoujiRenwu 类  中  的  成  员  变  量 height,weight,head,ear,mouth,hand,foot 被 分配 内 存 空 间 , 并 返 回 一个 引 用 给 zhubajie 当 再 创建 一 个对象 sunwukong 时 ,XiyoujiRenwu  类 中 的 成 员 变 量 height,weight,head,ear,mouth,hand,foot 再一次被分配内存空间,并返回一个引用给 sunwukong.sunwukong 的变量所占据的内存空间和 zhubajie 的变量所占据的内存空间是互 不相同的位置.内存模型如下图 4.3 所示

zhubajie

0xAB12

weight

height

head ear mouth hand foot

sunwukong

0x111A

weight

height

head ear mouth hand foot

 4.3   对象

4.3.2. 使用对象

对象不仅可以操作自己的变量改变状态,而且还拥有了使用创建它的那个类中的方法的

能力,对象通过使用这些方法可以产生一定的行为.

通过使用运算符”.”,对象可以实现对自己的变量访问和方法的调用.

1 对象操作自己的变量 对象的属性 .

对象创建之后,就有了自己的变量,即对象的实体.通过使用运算符”.”,对象可以实现对

自己的变量的访问.

2 对象调用类中的方法 对象的功能

对象创建之后,可以使用运算符”.”调用创建它的类中的方法,从而产生一定的行为功能. 当对象调用类中的一个方法时,方法中的局部变量被分配内存空间.方法执行完毕,局部变量 即刻释放内存.

在学习类的时候我们讲过 类中的方法可以操作成员变量.当对象调用方法时,方法中

出现的成员变量就是指该对象的成员变量

下面 的 例 子 3 中 , 有 两 个对象

zhubajie,sunwukong.

例子 3 效果如图 4.5

class XiyoujiRenwu

{ float height,weight;

String head, ear,hand,foot, mouth;

void speak(String s)

{ head="歪着头"; System.out.println(s);

}

}

class Example4_3

{  public static void main(String args[])

{ XiyoujiRenwu  zhubajie,sunwukong;//声明对象.

zhubajie=new  XiyoujiRenwu();  //为对象分配内存,使用 new 运算符和默认的构造方法. sunwukong=new  XiyoujiRenwu();

zhubajie.height=1.80f; //对象给自己的变量赋值. zhubajie.weight=160f; zhubajie.hand="两只黑手"; zhubajie.foot="两只大脚";  zhubajie.head="大头"; zhubajie.ear="一双大耳朵"; zhubajie.mouth="一只大嘴"; sunwukong.height=1.62f; //对象给自己的变量赋值. sunwukong.weight=1000f; sunwukong.hand="白嫩小手"; sunwukong.foot="两只绣脚"; sunwukong.head="绣发飘飘"; sunwukong.ear="一对小耳";  sunwukong.mouth="樱头小嘴"; System.out.println("zhubajie 的身高  "+zhubajie.height); System.out.println("zhubajie 的头  "+zhubajie.head); System.out.println("sunwukong 的重量  "+sunwukong.weight); System.out.println("sunwukong 的头  "+sunwukong.head); zhubajie.speak("俺老猪我想娶媳妇"); //对象调用方法. System.out.println("zhubajie 现在的头  "+zhubajie.head); sunwukong.speak("老孙我重 1000 斤,我想骗八戒背我"); //对象调用方法. System.out.println("sunwukong 现在的头  "+sunwukong.head);

}

}

我们知道 类中的方法可以操作成员变量,当对象调用该方法时,方法中出现的成员变 量就是指该对象的成员变量.在上述例子中,当对象 zhubajie 调用过方法 speak 之后,就将 自己的头修改成 ”外着头”.同样,对象 sunwukong 调用过方法 speak 之后,也就将自己的 头修改成 ”外着头”.

下面的例子 4 中,有两个对象 wanghong,lihong.

例子 4 效果如图 4.6

import java.applet.*; import java.awt.*; class Student

{  float math,english,sum;

float f(float k1,float k2)

{ sum=k1*math+k2*english;

return sum;

}

}

public class Example4_4 extends Applet

{  Student wanghong,lihong;

public void init()

{ wanghong=new Student();  lihong  =new Student(); wanghong.math=60.0f; wanghong.english=80f; lihong.math=70.0f; lihong.english=90.0f; wanghong.sum=wanghong.f(2.0f,2.0f); lihong.sum=lihong.f(2.0f,2.0f);

}

public void paint(Graphics g)

{ g.drawString("lihong sum= "+lihong.sum,12,45);

g.drawString("wanghong sum="+wanghong.sum,12,60);

}

}

在上述例子 4 中,当 lihong 调用方法 f 时,将值 2.0f 和 2.0 传递给方法的参数 x,y.方

法 f 将计算 2.0*math+2.0*english,这个计算式子中的变量 math,english 当然是指被 liong 操纵的 math,english,因此这个式子中的 math 的值是 70f,english 的值是 90f. 在下面的例子 5 中,我们用梯形类创建对象,该对象有计算自身面积的功能.

例子 5

class 梯形

{  float 上底,下底,高;

梯形()

{ 上底=60; 下底=40; 高=20;

}

梯形(float x,float y,float h)

{ 上底=x; 下底=y; 高=h;

}

float 计算面积()

{ float 面积; 面积=(上底+下底)*高/2.0f; return 面积;

}

void 修改高(float height)

{  高=height;

}

float 获取高()

{ return 高;

}

}

class Example4_5

{ public static void main(String args[])

{ 梯形 laderOne=new 梯形(),laderTwo=new 梯形(2.0f,3.0f,10); System.out.println("laderOne 的高是:"+laderOne.获取高()); System.out.println("laderTwo 的高是:"+laderTwo.获取高()); System.out.println("laderOne 的面积是:"+laderOne.计算面积()); System.out.println("laderTwo 的面积是:"+laderTwo.计算面积()); laderOne.修改高(10);

float h=laderOne.获取高();

laderTwo.修改高(h*2);

System.out.println("laderOne 现在的高是:"+laderOne.获取高()); System.out.println("laderTwo 现在的高是:"+laderTwo.获取高()); System.out.println("laderOne 现在的面积是:"+laderOne.计算面积()); System.out.println("laderTwo 现在的面积是:"+laderTwo.计算面积());

}

}