对象
出了这个类的一个实例.
创建对象
创建一个对象包括对象的声明和为对象分配内存两个步骤.
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.计算面积());
}
}