已阅读5页,还剩26页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
JAVA快速入门练习4 第4章实验方法4.1实验目标 (1)了解类、对象、方法的基本概念,方法的参数含义。 (2)参数和变量的作用域,定义和使用静态方法。 (3)方法定义和调用,包括有返回值和无返回值的方法的定义和调用。 (4)了解JAVA基本类库中的一些与原始数据类型密切相关的一些方法。 (5)递归和迭代机制及函数实现。 4.2实验说明本章实验教程将初步介绍JAVA类(class)、对象(object)和方法(method)的一些基本概念。 以下的实验包括4种类型,每种类型都用括号里面的字母表示D-例程,表示这是一个例子,要求练习者阅读指南和代码;I-交互式练习,练习者完成实验指定的简单任务,如修改部分代码,观察程序运行时的变化等;W-热身练习,练习者的编程工作量逐渐加大。 P-完整编程,要求练习者根据要求,完成完整的JAVA程序。 4.3实验准备从本实验教程光盘中拷贝Lab04文件目录到本地磁盘,如C:盘。 Lab04文件目录中将包含本次实验所需的所有资料。 Lab04的相关资料也可以从本实验教程的网站下载javaLab/lab04.zip4.4实验任务实验4.4.1:(D)初步介绍JAVA类、对象和方法1.使用JAVA开发包中的类JAVA程序由类(class)组成,类中包含方法(method)。 到目前为止,实验教程中涉及的程序只有一个类一个方法在应用程序中的main方法和在applet中的paint方法。 程序中还用到了类的其他方法,这些方法不是我们自己编写的,它们是JAVA开发包中的一部分。 例如使用类JOptionPane中的showMessageDialog和showInputDialog方法,无需编写整个代码,而是进行方法调用JOptionPane.showMessageDialog(null,Hi there!);String name=JoptionPane.showInputDialog(Whats yourname?);使用类JOptionPane中的方法,需要在程序的开头加上import语句import javax.swing.JOptionPane;使用了import语句,编译器才能在JAVA类库中的javax.swing包中找到类JOptionPane。 另外,类Integer的方法parseInt可以将为String表达形式的数字转化成int类型。 使用类Interger中的方法不必写一个import语句。 java.lang中的所有类(包括类Integer)都是自动导入到每一个Java程序之中的,程序不必显式地给出导入过程。 要使用Java其他库包中的类则需要显式地给出导入语句。 2.简单理解一下Java对象和类的关系Java对象(Object)是计算机存储区中用来存储特定类型数据的一个区域,这些特殊类型的数据是根据类(Class)来定义的。 举个简单例子程序清单4-1Student.java/Student.java public class Studentprivate int id;/学生ID privateString name;/姓名public Student(int id,String name)this.id=id;=name;public intgetID()return id;public voidsetID(int id)this.id=id;public StringgetName()return name;public voidsetName(String name)=name;这里定义了一个Student类,它有2个属性、4个实例方法和1个构造方法。 根据Student的数据结构,可以创建多个对象。 类的对象也被称作是类的实例(instance)。 3.JAVA的两种数据类型体系JAVA有两种数据类型原始数据类型(Primitive DataType)和引用数据类型(Reference DataType)。 原始数据类型在前面已经做过介绍,它的值就是一个数字、一个字符或一个布尔值。 而身为引用数据类型的变量又被称为是对象引用,实际上它的值是指向内存空间的引用(就是地址),该地址指向的内存中保存着变量所表示的一个值或一组值。 举个例子说明Student s1,s2;/在内存中分配两个引用数据类型变量的空间s1=new Student();/分配Student对象的数据空间,并把该空间的首地址0xabcdef赋给s1s2=s1;/将s1存储空间中的地址复制到s2的存储空间中如图4.1所示:图4.1引用数据类型举例由于变量s1和s2的值相同,即指向同一个内存地址,s1和s2实际上是同一个对象。 4.类的三种方法(method)Java类有三种方法构造方法(constructor),实例方法(instance method)和静态方法(static method)。 它们分别有不同的调用方式。 (1)构造方法(constructor)构造方法用于创建对象。 对象在使用前必须要初始化,即为对象分配数据空间。 调用构造方法创建一个Student对象Student s=new Student(123,he xiang);注意到类的构造方法与类同名,调用构造方法通常使用关键字new。 这里,首先为变量s分配一个引用空间;使用new关键字调用类的构造方法为Student类的对象分配数据空间;将数据空间的首地址赋给s。 (2)实例方法(instance method)对象创建后,就可以让它做一些操作。 为此,就要调用实例方法。 实例方法定义了一个对象的行为,其调用的格式如下对象引用.方法名(参数)objectReference.methodName(parameters)例如,调用Student对象s的getID方法s.getID(); (3)静态方法(static method)类JOptionPane的showMessageDialog和showInputDialog方法以及类Integer的parseInt方法的使用有一个相同点,其调用形式如下类名.方法名(参数)ClassName.methodName(parameters)以这种形式调用的方法称为静态方法(static method)。 静态方法定义的行为并不针对某个特定的对象。 注意这点与实例方法的不同。 另外,静态方法的方法头有关键字static,实例方法和构造方法没有此关键字。 实验4.4.2:(D)方法的参数Applet中的paint方法有如下的方法头定义public voidpaint(Graphics g)扩符()中的g是声明为Graphics类型的变量。 在方法头的扩符内声明的变量被称为是形式参数。 形式参数不需要初始化,因为方法调用时它(们)已经被自动地赋值。 在paint方法中,可以假设变量g已经指向了类Graphics的一个对象了。 在paint方法里,可以使用已经存在的Graphics对象来画图,比如调用方法drawString和drawLine。 下面的语句对Font类作了如下的实例化Font ft=new Font(Serif,Font.PLAIN,56);g.setFont(ft);第一句调用了一个构造方法来创建一个对象,此对象被变量ft引用。 在第二句中,我们没有调用Font对象ft的实例方法。 而是将ft作为参数传递给setFont方法,此方法为Graphics对象g的一个实例方法。 Java库中,类Graphics方法setFont的方法头定义如下public abstractvoid setFont(Font font)这里的形式参数font在setFont方法调用时自动接收实例化的Font对象ft为它的实际值。 形式参数接收的实际值被称为实际参数。 在上面的例子中,实际参数是ft。 类似地,main方法有类型为String(字符串数组)的形式参数public staticvoid main(Stringargs)实验4.4.3:(D)变量及其作用域1.Java有四种类型的变量本地变量(local variable)、实例变量(instance variable)、类变量(class variable)和参数(parameter)。 本地变量在方法中声明;实例变量和类变量在类体中、方法体外声明。 实例变量和类变量看起来比较类似,只是类变量是静态变量,使用static访问修饰符。 Java虚拟机(JVM)在方法或构造方法执行前为参数分配空间,并在消息处理完成后释放空间。 下面是Java类中声明变量的一般形式的伪代码(pseudocode)class someClassvisibility_modifier variable_type instanceVariableName;/Instance Variablevisibility_modifier staticvariable_type classVariableName;/Class VariablereturnType someMethod1()variable_type localVariableName;/Local VariablereturnType someMethod2(Type parameterName)/ParameterinstanceVariableName和classVariableName在someClass类体中声明,其中instanceVariableName是实例变量,classVariableName是类变量;localVariableName在someMethod方法中声明,是本地变量。 parameterName是方法someMehod2的形式参数(简称“形参”)。 2.变量是数据的标识。 上面的伪代码中变量名分别是instanceVariableName,classVariableName,localVariableName和parameterName。 变量名必须是合法的标识符,具体的要求如下 (1)不能使用保留字; (2)是字母、数字、美元符号“$”或下划线“_”的序列; (3)不能以数字开头,必须以字母、美元符号“$”或下划线“_”开头; (4)区分大小写,比如myName和MyName是不同的标识符。 合法的变量名如x、value- 1、$amount等;非法的变量名如2brother、room#、class(保留字)等。 就象给家里的每个孩子取不同名字,变量名应具有一定的含义,以增加程序的可读性。 3.变量的声明声明变量将在存储器中分配一定的空间,用于存储相应类型的数据,稍后可以使用变量名访问存储在该空间的数据。 注意,变量声明仅仅为变量分配内存空间,并没有实际地存储数据。 Java语言是一种强类型语言,即声明时必须指定变量的数据类型,编译器为其分配相应的存储空间。 有强类型语言,就有弱类型语言,比如VB、JAVASCRIPT编程语言,弱类型不一定需要指定数据类型,编译器会用相同的空间去分配各种类型。 变量的声明格式为:type identifier=value,identifier=value;以下是有效的变量声明int id;String name;4.变量的作用域Java中具体有以下四种类型的作用域成员变量作用域、本地变量作用域、参数作用域以及异常处理参数作用域。 图4.2Java变量作用域如图4.2所示,成员变量包括类变量和实例变量。 它们在类中定义,而不是在任何方法或者构造方法中定义。 成员变量的作用域是整个类体。 本地变量的作用域从该变量声明开始到定义此变量的代码块结束为止。 参数是指方法或构造方法的形式参数,用于传递数值给方法或构造方法。 参数的作用域是整个方法或构造方法。 异常处理参数跟参数相似,差别在于前者是传递参数给异常处理,而后者是传递给方法或构造方法。 异常处理参数的作用域处在catch和之间。 见下面的代码if(.)int i=17;.System.out.println(The valueof i=+i);/错误代码最后一行无法汇编,因为if块中定义的本地变量i已经超出作用域。 改正的方法是,将变量声明移到if语句块的外面,或者将println语句移动到if语句块中。 5.变量的的生命周期不同变量有不同作用域,作用域定义了变量在程序内存中的生命周期。 变量一旦离开其作用域,它所占的内存空间就会被Java虚拟机(JVM)标注为可垃圾回收,变量就无法被引用了。 本地变量必须在方法中声明。 这当然也包括方法中嵌入的代码块,如if、while或for代码块。 变量在它所声明的代码块中是本地的。 例如,方法体中声明的变量在此方法中是本地变量,在if块中声明的变量在此if块中是本地变量。 这意味着在花括号中声明的变量在花括号外不能使用。 实例变量是对象的组成部分,每个对象的实例都有属于自己的实例变量。 例如,Order类中声明了一个名为orderDate的实例变量,那么Order类的每个对象都有自己的orderDate,可以为自己的orderDate设定不同的值。 实例变量不能离开对象独立存在,因此,实例变量与包含它的对象的生命周期相同。 类变量的生存周期是从该类被JVM加载开始到释放该类结束。 当类第一次被引用时(通常情况是用new实例化类的第一个对象),类被加载到JVM。 类变量类似与全局变量,它的生存周期在变量中是最长的。 类变量被该类的所有对象共享,所以如果有十个Order对象,则类变量todayDate的值被十个对象共享,事实上,所有Order对象访问的是同一个todayDate。 6.编译、运行VariableScope.java程序,仔细阅读代码中的注释,理解Java各种变量的使用。 程序清单4-2VariableScope.java/VariableScope.java public class VariableScope/classVariableName类变量的作用域是整个类体static publicString classVariableName=类变量;/instanceVariableName实例变量的作用域是整个类体private int instanceVariableName=0;/参数intParameter的作用域是整个oneMethod方法体public voidoneMethod(int intParameter)/局部变量temp的作用域都是整个oneMethod方法体int temp=5;if(intParametertemp)/在不同作用域声明同名变量,在JAVA中是不允许的,下边的语句会报错/int temp=1;System.out.println(方法内部可以访问局部变量,局部变量temp=+temp);instanceVariableName=instanceVariableName+intParameter;public voidanotherMethod()System.out.println(类变量是+classVariableName);System.out.println(实例变量instanceVariableName=+instanceVariableName);public staticvoid main(Stringargs)/创建一个VariableScope对象/JVM载入VariableScope类,classVariableName生命周期开始VariableScope object1=new VariableScope();/可以通过类名或对象名访问VariableScope类的静态变量,例如System.out.println(使用类名访问+VariableScope.classVariableName);System.out.println(使用对象名访问+object1.classVariableName);/object1对象的实例变量instancevariable1,instancevariable2生命周期开始object1.oneMethod (6);object1.anotherMethod();/object1对象的实例变量instanceVariableName生命周期结束实验4.4.4:(I)定义和使用静态(static)方法1.先回顾一下这段Hello.java程序public classHellopublic staticvoid main(Stringargs)System.out.println(Hello,world!);注意这里static关键字的用法。 程序定义了一个静态的方法名为main,这意味着告诉Java编译器,此方法无需创建一个Hello类的对象即可调用。 简单理解static static-静态内存中指定位置用static修饰的变量和方法,实际上是指定了这些变量和方法在内存中分配有“固定位置”和“固定大小”。 static变量有点类似于C中的全局变量的概念;静态表示了内存的共享,即此类的所有对象都可以操控此块存储空间。 2.编译DrawX.java(见程序清单4-3),编写相应的ViewDrawX.html文件运行程序。 注意在运行DrawX.java之前要先编译GraphicsUtility.java(见程序清单4-4)。 程序清单4-3DrawX.java/DrawX.java/Draws3big Xs./使用类GraphicsUtility的一个方法来画每一个X.import java.applet.Applet;import java.awt.Graphics;import java.awt.Color;public class DrawX extends Appletpublic voidpaint(Graphics pen)setBackground(Color.black);pen.setColor(Color.white);GraphicsUtility.drawX(pen,0,0);GraphicsUtility.drawX(pen,4,0);GraphicsUtility.drawX(pen,29,35);/method paint(Graphics)/classDrawX.java窗口小程序显示三个“X”。 观察DrawX.java和GraphicsUtility.java源程序。 注意到DrawX.java中并没有使用画直线的drawLine方法,而是调用了GraphicsUtility类中定义的drawX方法。 GraphicsUtility类中的drawX方法可以在指定位置画出一个X,方法定义如下public staticvoid drawX(Graphics g,int x,int y)g.drawLine(x,y,x+200,y+130);g.drawLine(x,y+130,x+200,y);/method drawX(Graphics,int,int)方法的定义包含方法名和方法体。 drawX的方法名为public staticvoid drawX(Graphics g,int x,int y)圆括号()中包含了此方法的多个形式参数及其数据类型。 方法体为花括号里包含的代码。 程序清单4-4GraphicsUtility.java import java.awt.Graphics;public class GraphicsUtilitypublic staticvoid drawX(Graphics g,int x,int y)g.drawLine(x,y,x+200,y+130);g.drawLine(x,y+130,x+200,y);/method drawX/classGraphicsUtility对一个方法的使用,称为调用(call)。 类DrawX中的paint方法三次调用了类GraphicsUtility中的drawX方法GraphicsUtility.drawX(pen,0,0);GraphicsUtility.drawX(pen,4,0);GraphicsUtility.drawX(pen,29,35);在三个不同位置上画出三个“X”。 在调用drawX方法时,形式参数被自动初始化为实际参数。 例如,paint方法中第一次调用drawX时,Java虚拟机执行如下等效语句Graphics g=pen;int x=0;int y=0;用于接收传递值的变量称为形式参数(formal parameter);被传递给方法的值称为实际参数(actual parameter)。 因为形式参数在方法调用时被自动赋值,所以在方法体内不需要初始化。 在方法体中声明的变量叫做本地变量(local variable)。 与形式参数不同,本地变量必须在方法体内初始化。 注意GraphicsUtility既不是一个application也不是一个applet。 它不包含main方法也不包含“extendsApplet”。 修改DrawX.java程序中调用drawX方法的实际参数值,重新编译和运行程序,观察“X”在窗口中位置的变化。 3.练习写一个静态方法。 为类GraphicsUtility写一个新方法drawZ,这个方法和drawX相似,只是前者画“Z”后者画“X”。 GraphicUtility.java现在包含两个方法方法drawZ和方法drawX。 方法drawZ应该以以下语句作为开头public staticvoid drawZ(Graphics g,int x,int y)其中x和y为所画“Z”的左上角。 “Z”的大小为20像素宽、30像素高。 编写DrawXZ.java,通过调用类GraphicsUtility的方法drawZ和方法drawX来显示两个Z和一个X。 在一个宽201像素和高110像素的applet显示屏(HTML文件ViewDrawXZ.htmlz中规定的)上,两个Z的左上角位置相为(0,0)和(180,0),X的左上角位置为(90,50)。 程序清单4-5ViewDrawXZ.html此applet将画一些X和Z。 能很好地工作?定义方法drawZ时,注意方法体前后都有花括号,同时确定方法drawZ是定义在类GraphicsUtility中。 实验4.4.5:(D)有返回值的方法1.观察MathUtility.java程序源代码。 程序清单4-6MathUtility.java/MathUtility.java public class MathUtilitypublic staticdouble power(float base,int exponent)if(exponent0)exponent=0-exponent;base=1/base;/if exponent0double product=1;for(int i=0;i );return0;/if exponent0long product=1;for(int i=0;i 虽然这些方法有相同的名字,但方法头中定义的形式参数却不一样。 其中一个power方法的两个参数为类型float和类型int,另外一个power方法的参数都为类型int。 Java中,同一个类中的2个或2个以上的方法可以有同一个名字,只要它们的参数声明不同即可。 这种方法定义称为“方法重载(method overload)”。 当调用一个重载方法时,虚拟机会根据不同的参数样式来选择合适的方法执行。 不同的参数样式是指参数的类型和(或)数量不同。 2.MathUtility.java的两个power方法不仅参数样式不同,它们的返回值也不同。 方法的返回值在方法头中确定。 第一个power方法返回一个double值,第二个power方法返回一个long型的值。 编译运行程序PowerTest1.java。 程序源代码见程序清单4-7。 程序清单4-7PowerTest1.java/PowerTest1.java/Tests thetwo powermethods/in classMathUtility publilass PowerTest1public staticvoid main(Stringargs)final int intBase=2;final int exponent=50;final float floatBase=intBase;long longPower=MathUtility.power(intBase,exponent);double doublePower=MathUtility.power(floatBase,exponent);System.out.println();/blank lineSystem.out.println(intBase+上调为+exponent+时指数是:);System.out.println();System.out.println(+longPower+(long);System.out.println(+doublePower+(double unformatted);/method main/class PowerTest1程序分别调用类MathUtility的两种power方法计算2的50次方,并以非格式化方式显示double类型的运算结果。 非格式化的double数值,以科学记数法显示,如下1.125899906842624E15意为1.125899906842624乘上10的15次方。 比较大的浮点数(float或double)都默认采用科学记数法表示。 浮点数在内存中的存储也类似科学记数方式,只是它涉及的指数为2而非10。 PowerTest1.java中调用类MathUtility的power方法long longPower=MathUtility.power(intBase,exponent);double doublePower=MathUtility.power(floatBase,exponent);这两个power方法产生各自的返回值,并分别赋值给longPower和doublePower。 这类似数学中的函数y=f(x)z=g(x,y)Java中的“方法”,在其他编程语言中被称为“函数”。 在Pascal中,有返回值的子程序称为“函数”,没有返回值的子程序称为“过程”。 在C和C+中,所有子程序不管是否有返回值,统称为“函数”。 有返回值的方法在开头要声明返回类型,而且以一个返回语句作为结束。 例如,类MathUtility的两个power方法都以return product;结束。 有返回值的方法中,返回语句包含return关键字以及返回值的表达式。 在这个例子中,每一个power方法返回变量product。 3.看一下计算指数的算法for(int i=0;i 编译并运行PowerTest2.java看两个方法是如何处理负数指数的。 程序清单4-8PowerTest2.java/PowerTest2.java/Tests thetwo powermethods/in classMathUtility publilass PowerTest2public staticvoid main(Stringargs)final intintBase=2;final intexponent=-3;final floatfloatBase=intBase;long longPower=MathUtility.power(intBase,exponent);double doublePower=MathUtility.power(floatBase,exponent);System.out.println();/blank lineSystem.out.println(intBase+调整为+exponent+时指数为:);System.out.println();System.out.println(+longPower+(long);System.out.println(+doublePower+(double);System.out.println();/method main/class PowerTest2注意到数x的负指数是值为1/x的正指数。 所以在浮点版本的power方法中,如果exponent是负数,那么首先将其替换为相应的正数指数形式。 而整数版本的power方法中,如果expo为负数的话,将产生一个错误消息并返回0值。 错误消息通过System.err打印出,System.err为标准错误流,而不是通过标准输出流System.out输出。 System.out和System.err都可以通过DOS窗口显示。 4.PowerTest3.java程序除main方法外,还包含一个静态方法testPower以完成实际的测试。 程序清单4-9PowerTest3.java/PowerTest3.java/Tests thetwo powermethods/in classMathUtility publilass PowerTest3public staticvoid main(Stringargs)System.out.println();/blank line/当在类内部定义的一个静态方法被调用时/可以带有类名也可以不带类名testPower(2,50);/一个如下定义的调用testPower方法.PowerTest3.testPower(2,61);/同样可以,通常对静态方法如此调用.PowerTest3.testPower(2,64);/method mainpublic staticvoid testPower(intintBase,intexponent)long longPower=MathUtility.power(intBase,exponent);floatfloatBase=intBase;double doublePower=MathUtility.power(floatBase,exponent);System.out.println(intBase+上调到+exponent+时指数为:);System.out.println();System.out.println(+longPower+(long);System.out.println(+doublePower+(double unformatted,scientific notation);System.out.println();/testPower/class PowerTest3前面已经讲到过,static方法的调用形式为ClassName.methodName(parameters)然而,在类内部调用本身的静态方法时,类
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 安全出行美术课件
- 中学生消防安全教育课件
- 意外安全知识课件
- 《中药学综合知识与技能》模拟试卷(五)
- 中班安全课课件
- 工程类国企考试题及答案
- 国企《战略管理岗》招聘考试SWOT分析实战演练卷
- 2019年国考申论真题及解析
- 1、外来人员安全教育试题
- 国家金融监管参考文献集
- 急性阑尾炎伴有弥漫性腹膜炎的护理查房
- 环境礼仪培训课件
- +2.2+更好发挥政府作用高中政治统编版必修二经济与社会+
- 十五五林业草原发展规划纲要
- 农户生计韧性的新挑战与应对策略
- GB/T 12406-2022表示货币的代码
- WPS图文并茂技巧2025年考试要点试题及答案
- 拆旧建屋合同协议书
- 2025年春江苏开放大学维修电工实训第3次形考作业答案
- 2025年CSCO胰腺癌诊疗指南解读
- 蜜雪冰城加盟合同(2025年版)
评论
0/150
提交评论