成员方法

4.4




成员方法描述对象所具有的功能或操作,反映对象的行为,
是具有某种相对独立功能的程序模块。它与过去所说的子程序、
函数等概念相当。一个类或对象可以有多个成员方法,对象通过
执行它的成员方法对传来的消息作出响应,完成特定的功能。成
员方法一旦定义,便可在不同的程序段中多次调用,故可增强程
序结构的清晰度,提高编程效率。例如,下面的成员方法可完成
两个整数的求和运算,一旦完成了它的编写和调试,便可在程序
中随时调用该方法,传递不同的参数来完成任意两个整数的求和
运算。
第4章 类 与 对 象
int add(int x,int y)
{ int z;
z=x+y;
return(z);
}
第4章 类 与 对 象
4.4.1
成员方法的分类
为了便于理解,我们先来看看成员方法的分类。我们可以
从不同的角度出发,对成员方法进行分类。
从成员方法的来源看,可将成员方法分为:
(1) 类库成员方法。这是由Java类库提供的,用户只需要按
照Java提供的调用格式去使用这些成员方法即可。
(2) 用户自己定义的成员方法。这是为了解决用户的特定
问题,由用户自己编写的成员方法。程序设计的主要工作就是
编写用户自定义类、自定义成员方法。
第4章 类 与 对 象
从成员方法的形式看,可将成员方法分为:
(1) 无参成员方法。例如,void printStar( ){ ……}
(2) 带参成员方法。例如,int add(int x,int y){ …… }
当然,还可以从成员方法的功能上将其分为数学运算方法、
字符处理方法、图形方法等。介绍上面分类的主要目的是为了
帮助我们理解类库成员方法、带参成员方法等几个最常用的名
词。实际上,类库成员方法可以是无参成员方法,也可以是带
参成员方法。同样,某个带参成员方法既可能是类库成员方
法,也可能是用户自已定义的成员方法。
第4章 类 与 对 象
4.4.2
声明成员方法的格式
在Java程序中,成员方法的声明只能在类中进行,格式如
下:
[修饰符] 返回值的类型 成员方法名(形式参数表)throw
[异常表]
{
说明部分
执行语句部分
}
第4章 类 与 对 象
成员方法的声明包括成员方法头和方法体两部分,其中:
成员方法头确定成员方法的名字、形式参数的名字和类型、返
回值的类型、访问限制和异常处理等;方法体由包括在花括号
内的说明部分和执行语句部分组成,它描述该方法功能的实现。
第4章 类 与 对 象
在成员方法头中:
(1) 修饰符。修饰符可以是公共访问控制符public、私有访
问控制符private、保护访问控制符protected等访问权限修饰
符,也可以是静态成员方法修饰符static、最终成员方法修饰符
final、本地成员方法修饰符native、抽象成员方法修饰符abstract
等非访问权限修饰符。访问权限修饰符指出满足什么条件时该
成员方法可以被访问。非访问权限修饰符指明数据成员的使用
方式。
第4章 类 与 对 象
(2) 返回值的类型。返回值的类型用Java允许的各种数据类
型关键字(例如,int,float等)指明成员方法完成其所定义的功
能后,运算结果值的数据类型。若成员方法没有返回值,则在
返回值的类型处应写上void关键字,以表明该方法无返回值。
(3) 成员方法名。成员方法名也就是用户遵循标识符定义
规则命名的标识符。
第4章 类 与 对 象
(4) 形式参数表。成员方法可分为带参成员方法和无参成
员方法两种。对于无参成员方法来说则无形式参数表这一项,
但成员方法名后的一对圆括号不可省略;对于带参成员方法来
说,形式参数表指明调用该方法所需要的参数个数、参数的名
字及其参数的数据类型,其格式为:
(形式参数类型1 形式参数名1,形式参数类型2 形式参数
名2,……)
(5) throw [异常表]。它指出当该方法遇到一些方法的设计
者未曾想到的问题时如何处理。
第4章 类 与 对 象
4.4.3
方法体中的局部变量
方法体描述该方法所要完成的功能,它由变量声明语句、
赋值语句、流程控制语句、方法调用语句、返回语句等Java允许
的各种语句成分组成,是程序设计中最复杂的部分,几乎会用
到我们已经学习过的和将要学习的绝大多数内容。本着由浅入
深、循序渐进的原则,这里先提请大家注意:
(1) 在方法体内可以定义本方法所使用的变量,这种变量是
局部变量,它的生存期与作用域是在本方法内。也就是说局部
变量只在本方法内有效或可见,离开本方法则这些变量被自动
释放。
第4章 类 与 对 象
(2) 方法体内定义变量时,变量前不能加修饰符。
(3) 局部变量在使用前必须明确赋值,否则编译时会出错。
(4) 在一个方法内部,可以在复合语句中定义变量,这些
变量只在复合语句中有效,这种复合语句也被称为程序块。下
面的示例程序C4_11.java中指出了这一问题。
第4章 类 与 对 象
【示例程序c4_10.java】 局部变量及其用法。
public class c4_10
{
public static void main(String[ ] args)
{ int a=2,b=3;
int f=add(a,b); //调用add方法
System.out.println("f="+f);
//System.out.println("z="+z);错,z在add方法内,离开add则被清除
}
第4章 类 与 对 象
static int add(int x,int y)
{ //public int zz;错误的语句,在局部变量zz前误加了public修饰符
int z,d; //本方法中定义的变量z,d
z=x+y; //若写成 z=x+d;就会出错,因为d还没有赋值就使用
return z;
}
}
第4章 类 与 对 象
【示例程序c4_11.java】 复合语句中声明的局部变量。
public class c4_11
{
public static void main(String[ ] args)
{ int a=2,b=3;
{ int z=a+b; //复合语句中声明的变量z
System.out.println("z="+z);
}
// System.out.println("z="+z);错,z只在复合语句中有效
}
}
第4章 类 与 对 象
4.4.4
成员方法的返回值
若方法有返回值,则在方法体中用return语句指明要返回的
值。其格式为:
return 表达式;
或 return(表达式);
其中表达式可以是常量、变量、对象等,且上述两种形式
是等价的。此外,return语句后面表达式的数据类型必须与成员
方法头中给出的“返回值的类型”一致。
第4章 类 与 对 象
例如:
return z;
return(z);
return(x>y?x:y);
if(x>y) return true;
else return(false);
都是合法的,且“return z;”与“return(z);”等价。
第4章 类 与 对 象
4.4.5
形式参数与实际参数
一般来说,可通过如下的格式来引用成员方法:
成员方法名(实参列表)
但在引用时应注意下述问题:
(1) 对于无参成员方法来说,是没有实参列表的,但方法名
后的括弧不能省略。
(2) 对于带参数的成员方法来说,实参的个数、顺序以及它
们的数据类型必须与形式参数的个数、顺序以及它们的数据类
型保持一致,各个实参间用逗号分隔。实参名与形参名可以相
同也可以不同。
第4章 类 与 对 象
(3) 实参也可以是表达式,此时一定要注意使表达式的数据
类型与形参的数据类型相同,或者使表达式的类型按Java类型转
换规则达到形参指明的数据类型。
(4) 实参变量对形参变量的数据传递是“值传递”,即只能由
实参传递给形参,而不能由形参传递给实参。程序中执行到引
用成员方法时,Java把实参值拷贝到一个临时的存储区(栈)中,
形参的任何修改都在栈中进行,当退出该成员方法时,Java自动
清除栈中的内容。
下面我们通过一个程序来说明上述各点。
第4章 类 与 对 象
【示例程序c4_12.java】
public class c4_12
{
static void add(double x,double y)
{ double z;
z=x+y;
System.out.println("z="+z);
x=x+3.2;y=y+1.2;
System.out.println("x="+x+"/ty="+y);
}
第4章 类 与 对 象
static double add1(double y1,double y2)
{ double z;
z=y1+y2+2.9;
return z;
}
public static void main(String[ ] args)
{ int a=2,b=7;
double f1=2,f2=4,f3;
add(a,b);// 按Java的类型转换规则达到形参类型
System.out.println("a="+a+"/tb="+b);
第4章 类 与 对 象
// f3=add1(f1, f2, 3.5);错,实参与形参参数个数不一致
f3=2+add1(f1,f2);
System.out.println("f1="+f1+"/tf2="+f2+"/tf3="+f3);
}
}
该程序的运行结果如下:
z=9.0
x=5.2 y=8.2
a=2 b=7
f1=2.0 f2=4.0 f3=10.9
第4章 类 与 对 象
【示例程序c4_13.java】
public class c4_13
{
static void add(double x,double y)
{ double z;
z=x+y;
System.out.println("z="+z);
}
static double add1(double y1,double y2)
{ double z;
z=y1+y2+2.9;
return z;
}
第4章 类 与 对 象
public static void main(String[ ] args)
{ int a=2,b=7;
double f1=2,f2=4,f;
add(a,add1(f1,f2));
}
}
运行结果:
10.9
第4章 类 与 对 象
4.4.6
成员方法的引用方式
成员方法的引用可有下述几种方式。
1
.方法语句
成员方法作为一个独立的语句被引用。例如, 程序
c4_12.java中的“add(a,b);”语句就是这种形式。
2
.方法表达式
成员方法作为表达式中的一部分,通过表达式被引用。例
如,程序c4_12.java中的“f3=2+add1(f1,f2);”语句就是这种形式。
第4章 类 与 对 象
3
.方法作为参数
一个成员方法作为另一个成员方法的参数被引用。例如,
程序c4_13.java中的“add(a,add1(f1,f2));”语句就是这种形式的
代表。更为典型的是,在递归的成员方法中,一个成员方法作
为它自身的参数被引用。
第4章 类 与 对 象
4
.通过对象来引用
这里有两重含义,一是通过形如“对象名.方法名”的形式来
引用对象,二是当一个对象作为成员方法的参数时,通过这个
对象参数来引用对象的成员方法。例如,程序c4_3.java的
“Dane.ShowDog(g,25,25);”语句,成员方法ShowDog( )本身通过
对象Dane来引用;同时,通过作为参数的对象g引用了
Graphics类的成员方法drawString( )。
第4章 类 与 对 象
4.4.7
引用成员方法时应注意的事项
首先,当一个方法引用另一个方法时,这个被引用的方法
必须是已经存在的方法。除了这个要求之外,还要视被引用的
成员方法存在于何处而做不同的处理。
(1) 如果被引用的方法存在于本文件中,而且是本类的方
法,则可直接引用。我们前面列举的例子基本上都是这种情况。
(2) 如果被引用的方法存在于本文件中,但不是本类的方
法,则要考虑类的修饰符与方法的修饰符来决定是否能引用。
第4章 类 与 对 象
(3) 如果被引用的方法不是本文件的方法而是Java类库的方
法,则必须在文件的开头处用import 命令将引用有关库方法所
需要的信息写入本文件中。例如,前几章用来在屏幕指定位置
上显示一个字符串的drawString( ) 方法是Java类库Graphics类中
的一个方法,而Graphics类存放在java.awt包中,因此,我们在
程序文件的开头处写上了“import java.awt.*;”语句,指出awt包
中的方法在本文件中要引用。
(4) 如果被引用的方法是用户在其他的文件中自己定义的方
法,则必须通过加载用户包的方式来引用。这部分内容将在5.5
节“接口与包”中讲述。
第4章 类 与 对 象
4.4.8
成员方法的递归引用
我们前面讲述的程序都以严格的层次方式在一个方法中调
用另一个方法。然而,对于某些实际问题,方法调用自身会使
程序更为简洁清晰,而且会使程序的执行逻辑与数理逻辑保持
一致。例如,数学中对于N!的定义是:
1 (当N=0时)
N!=
N*(N-1)! (当N>0时)
第4章 类 与 对 象
这个定义是递归的,即在N!=N*(N-1)!中,(N-1)!实际上
是N!的减1递推。对于这样的问题,我们可以构造循环来求
解,即用1*2*3*……*(n-1) *n的算式求得结果。但是,由于它
的定义本身是递归的,用递归算法实现则更符合数理逻辑。例
如,求4!的过程可表示成图4.9所示的形式。
第4章 类 与 对 象
图4.9 求4!的递归过程
4!
4*3!
3*2!
2*1!
1*0!
第4章 类 与 对 象
成员方法的递归引用就是指在一个方法中直接或间接引用
自身的情况。例如:
int f1(int n)
{
int p;
p=f1(n-1)
return p;
}


第4章 类 与 对 象
在这个例子中,方法f1( )中引用了f1( )本身,这种引用是直
接引用。
int f1(int n) int f2(int m)
{ {
int p; int s;
p=f2(n-1); s=f1(m+2);
return p; return s;
} }




第4章 类 与 对 象
【示例程序c4_14.java】 编程计算4!的值。
public class c4_14
{ static int fac(int n)
{ int fa;
if(n==0)
fa=1;
else
fa=n*fac(n-1); //递归引用自身
return fa;
}
第4章 类 与 对 象
public static void main(String[ ] args)
{ int n=4;
int f1=fac(n); //引用fac( )方法
System.out.println("4!="+f1);
}
}
该程序的输出结果是:
4!=24
第4章 类 与 对 象
图4.10 计算4!的成员方法fac递归引用关系
第4章 类 与 对 象
从图中可以看到求4!时,main方法引用fac(4)方法,fac(4)
引用fac(3),fac(3) 引用fac(2),fac(2)引用fac(1),fac(1)引用
fac(0),fac(0)方法得到确定值1,回归得到fac(1)=1,再回归得
到fac(2)=2,再回归得到fac(3)=6,最后再回归得到fac(4)=24,
fac( )方法共被引用了5次。
第4章 类 与 对 象
【示例程序c4_15.java】 编程求出Fibonacci数列的第8项
public class c4_15
{
public static void main(String[ ] args)
{ int n=8; int f8=fibo(n); System.out.println("f8="+f8); }
static int fibo(int n)
{ if(n==1)return 1;
else if(n==2)return 1;
else return (fibo(n-1)+fibo(n-2));
}
}
程序的执行结果为:
f8=21
第4章 类 与 对 象
4.4.9 static
修饰的静态方法
用static修饰符修饰的方法被称为静态方法,它是属于整个
类的类方法。不用static修饰符限定的方法,是属于某个具体类
对象的方法。static方法使用特点如下:
(1) static方法是属于整个类的,它在内存中的代码段将随
着类的定义而分配和装载。而非static的方法是属于某个对象的
方法,当这个对象创建时,在对象的内存中拥有这个方法的专
用代码段。
(2) 引用静态方法时,可以使用对象名做前缀,也可以使
用类名做前缀;
第4章 类 与 对 象
(3) static方法只能访问static数据成员,不能访问非static数
据成员,但非static方法可以访问static数据成员。
(4) static方法只能访问static方法,不能访问非static方法,
但非static方法可以访问static方法。
(5) static方法不能被覆盖,也就是说,这个类的子类,不
能有相同名、相同参数的方法。
(6) main方法是静态方法。在Java的每个Application程序
中,都必须有且只能有一个main方法,它是Application程序运
行的入口点。
第4章 类 与 对 象
例如:
class f
{ int d1;
static int d2;
void me( ){ ┅ }
static void me1( ){ ┅ }
static void me2( )
{ me1( ); //合法引用
d1=34; //错,引用了非static数据成员
me( ); //错,引用了非static方法
第4章 类 与 对 象
d2=45; //合法
}
}
class f1 extends f
{
void me1( ){┅} //错,不能覆盖类的方法
}
第4章 类 与 对 象
4.4.10
数学函数类方法
作为static方法的典型例子,我们来看看Java类库提供的实现
常用数学函数运算的标准数学函数方法,这些方法都是static方
法。标准数学函数方法在Java.lang.Math类中,使用方法比较简
单,格式如下:
类名.数学函数方法名( 实参表列 )
Java.lang.Math类提供的数学函数方法见表4.1。
第4章 类 与 对 象
表4.1 Java.lang.Math
类提供的数学函数方法
函 数 方 法功 能
public static double sin(double a) 正弦函数
public static double cos(double a) 余弦函数
public static double tan.(double a) 正切函数
public static double asin(double a) 反正弦函数
public static double acos(double a) 反余弦函数
public static double atan(double a) 反正切函数
public static double toRadians(double a) 将度转换为弧度
public static double toDegrees(double a) 将弧度转换为度
public static double exp(double a) 指数函数
public static double log(double a) 自然对数
public static double sqrt(double a) 平方根
第4章 类 与 对 象
表4.1 Java.lang.Math
类提供的数学函数方法
public static double IEEEremainder(double f1,double
f2)
两个数相除的余数
public static double ceil(double a)
获取不小于指定double数的最小双精度
实数
public static double floor(double a) 获取不大于指定double数的最小双精度
实数
public static double rint(double a) 获取最接近指定double数的整数
public static double atan2(double a,double b) 获取指定double数相除的反正切值
public static double pow(double a,double b) a的b次方
public static int round(float a) 获取最接近指定数的整数
public static long round(double a) 获取最接近指定数的数
public static double random(double a) 获取一个大于等于0且小于1的随机数
public static int abs(int a) 取绝对值
第4章 类 与 对 象
表4.1 Java.lang.Math
类提供的数学函数方法
public static long abs(long a) 取绝对值
public static float abs(float a) 取绝对值
public static double abs(double a) 取绝对值
public static int max(int a,int b) 获取两个指定数的最大值
public static long max(long a,long b) 获取两个指定数的最大值
public static float max(float a,float b) 获取两个指定数的最大值
public static double max(double a,double b) 获取两个指定数的最大值
public static int min(int a,int b) 获取两个指定数的最小值
public static long min(long a,long b) 获取两个指定数的最小值
public static float min(float a,float b) 获取两个指定数的最小值
public static double min(double a,double b) 获取两个指定数的最小值
第4章 类 与 对 象
【示例程序c4_16.java】
public class c4_16
{ public static void main(String[ ] args)
{double a=2,b=3;
double z1=Math.pow(a,b); //引用Math类的pow方法求a的b次方
double z2=Math.sqrt(9); //引用Math类的sqrt方法求9的平方根
System.out.print("z1="+z1);
System.out.println("/tz2="+z2);
}
}
程序的运行结果为:
z1=8.0 z2=3.0
第4章 类 与 对 象
4.4.11 final
修饰的最终方法
在面向对象的程序设计中,子类可以利用重载机制修改从
父类那里继承来的某些数据成员及成员方法,这给程序设计带
来方便的同时,也给系统的安全性带来了威胁。为此,Java语
言提供了final修饰符来保证系统的安全。用final修饰符修饰的
方法称为最终方法,如果类的某个方法被final修饰符所限定,
则该类的子类就不能覆盖父类的方法,即不能再重新定义与此
方法同名的自己的方法,而仅能使用从父类继承来的方法。可
见,使用final修饰方法,就是为了给方法“上锁”,防止任何继
承类修改此方法,保证了程序的安全性和正确性。
第4章 类 与 对 象
【示例程序c4_17.java】
class a1
{
final int add(int x,int y) //用final修饰符修饰的最终方法
{ return(x+y); }
int mul(int a,int b)
{ int z=0;
z=add(1,7)+a*b;
return z;
}
}
public class c4_17 extends a1 //由类c4_17是类a1的子类
{
第4章 类 与 对 象
/* int add(int x,int y)
{ return(x+y+2); } 子类c4_17企图覆盖父类a1的final方法,这是非法的 */
public static void main(String[ ] args)
{ int a=2,b=3,z1,z2;
c4_17 p1=new c4_17( );
z1=p1.add(a,b); //子类可以引用父类的final方法
z2=p1.mul(a,b);
System.out.println("z1="+z1);
System.out.println("z2="+z2);
}
}
运行结果:
z1=5 z2=14
第4章 类 与 对 象
4.4.12 native
修饰的本地方法
修饰符native修饰的方法称为本地方法,此方法使用的目的
是为了将其他语言(例如C、C++、FORTRAN、汇编等)嵌入
到Java语言中。这样Java可以充分利用已经存在的其他语言的程
序功能模块,避免重复编程。
在Java程序中使用native方法时应该特别注意平台问题。由
于native方法嵌入其他语言书写的模块是以非Java字节码的二进
制代码形式嵌入Java程序的,而这种二进制代码通常只能运行
在编译生成它的平台之上,所以整个Java程序的跨平台性能将
受到限制或破坏,除非native方法引入的代码也是跨平台的。详
细内容本书不再介绍,有兴趣者请参阅Java手册
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值