第4章 Java的类别方法
4-1 模组化程式设计
4-2 程序是一个黑盒子
4-3 Java的类别方法
4-4 Java的类别变数和变数范围
4-5 类别方法的过载
4-6 递回程式设计
4-7 Math数学类别的类别方法
4-1 模组化程式设计-模组
模组化是一种解决问题的方法,把一件大型的工作切割成无数的小工作,切割的工作属於结构化分析的范畴,我们最常使用的是「由上而下的设计方法」(Top-down Design),主要是以程序为单位来切割工作,也就是所谓的「程序式程式设计」(Procedural Design).
4-1 模组化程式设计-由上而下的设计方法
由上而下的设计方法是在面对问题时,先考虑将整个解决问题的方法分解成数个大「模组」(Modules),然后针对每一个大模组,一一分割成数个小模组,如此一直细分,最后等这些细分小问题的小模组完成后,再将它们组合起来,如此一层层的向上爬,完成整个软体系统或应用程式的设计.
例如:玩拼图游戏一定会先将整个拼图粗分为数个区域,等每一个区域都拼好后,整张拼图也就完成了.
4-1 模组化程式设计-注意事项
独立性:每一个分割模组间的关联性愈少,处理起来就会愈快.所谓独立性,是指当处理某一个子问题时,无需考虑到其它子问题.换一句话说,独立性是要将每一个问题都定义成一件简单且明确的问题.
结合问题:小心的控制子问题间的结合方法,而且要注意结合这些子问题的逻辑顺序,避免语焉不详的结果.
子问题间的沟通:虽然独立性可以减少各问题间的关联性,但是并无法避免掉全部的沟通.
4-2 程序是一个黑盒子-说明
在程式码执行程序称为呼叫(Subroutines Call) .
程序如同一个「黑盒子」(Black Box),只要告诉我们如何使用这个黑盒子的「使用介面」(Interface)即可,如下图所示:
4-2 程序是一个黑盒子-规则
在使用程式语言撰写程序时,有一些规则可供参考,如下所示:
程序的使用介面需要直接,良好定义和容易了解.
在使用程序时,我们不需要知道任何有关内部实作的问题,唯一需要知道的是如何使用它的使用介面.
在实作程序时,我们并不用考量或知道到底是谁需要使用此程序,只需满足使用介面定义的输入参数和传回值即可.
4-2 程序是一个黑盒子-语法与语意
程序的「语法」(Syntactic)是说明程序需要传入何种资料型态的「参数」(Parameters)和传回值.
「语意」(Semantic)是指出这个程序可以作什麼事
在撰写程序时,我们需要了解程序的语法规则,在使用程序时需要了解程序的语意规则,以正确的呼叫程式.
4-3 Java的类别方法
4-3-1 建立Java的类别方法
4-3-2 类别方法的参数传递
4-3-3 类别方法的传回值
4-3-4 传值或传址参数
4-3 Java的类别方法
在Java的程序属於一种类别的成员,称为「方法」(Method),在Java的程序或函数称为方法.
Java的方法可以分为两种,如下所示:
属於类别的「类别方法」(Class Methods)
物件的「实例方法」(Instance Methods)
Java的类别方法就是其它程式语言所谓的程序和函数.
4-3-1 建立Java的类别方法-语法
Java语言的类别方法是由方法名称和程式区块所组成,其语法格式如下所示:
存取叙述 static 传回值型态 方法名称( 参数列 )
{
……
程式叙述;
……
}
4-3-1 建立Java的类别方法-存取叙述修饰子
「存取叙述」(Access Specifier)也一种修饰子,可以是public和private,如下所示:
public:这个方法可以在程式任何地方进行呼叫,甚至是其它类别Class.
private:这个方法只能在同一个类别Class内进行呼叫.
4-3-1 建立Java的类别方法-范例
例如:显示讯息字串的printMsg()方法,如下所示:
private static void printMsg()
{
System.out.println("欢迎使用Java程式设计!");
}
上述方法的传回值为void,表示没有传回值,方法名称为printMsg,在括号内定义传入的参数列,不过此方法并没有任何参数,在「{」和「}」括号内是方法的程式区块.
4-3-1 建立Java的类别方法-呼叫
(语法)
Java方法的呼叫需要使用类别名称或方法名称,其语法格式如下所示:
方法名称( 参数列 );
类别名称.方法名称( 参数列 );
4-3-1 建立Java的类别方法-呼叫
(范例)
因为printMsg()方法没有传回值和参数列,所以呼叫方法只需使用方法名称加上空括号,如下所示:
printMsg();
上述呼叫的方法因为在同一个类别,所以省略类别名称,如果是在其他类别呼叫此类别方法,例如:public修饰子的add2Ten()方法,其呼叫方式如下所示:
Ch4_3_1.add2Ten();
上述程式码「.」运算子前的Ch4_3_1就是类别名称.
4-3-2 类别方法的参数传递-说明
Java方法的参数列是资讯传递的机制,可以从外面将资讯送入程序的黑盒子,参数列是方法的使用介面.
一个方法如果拥有参数列,在呼叫方法时,传入不同的参数就可以产生不同的执行结果.
4-3-2 类别方法的参数传递-范例
例如:printTriangle()方法传入不同字元和层数,就可以显示不同大小和字元的文字三角形,如下所示:
static void printTriangle(char ch, int level)
{
int i, j;
for ( i = 1; i <= level; i++)
{
for ( j = 1; j 0,使用n!定义的第2条计算阶层函数4!的值,如下所示:
4!=4*3*2*1=24
因为阶层函数本身拥有递回特性.可以将4!的计算分解成子问题,如下所示:
4!=4*(4-1)!=4*3!
现在3!的计算成为一个新的子问题,必须先计算出3!值后,才能处理上述的乘法.
4-6-2 递回的阶层函数-过程2
同理将子问题3!继续分解,如下所示:
3! = 3*(3-1)! = 3*2!
2! = 2*(2-1)! = 2*1!
1! = 1*(1-1)! = 1*0! = 1*1 = 1
最后在知道1!的值后,接著就可以计算出2!~4!的值,如下所示:
2! = 2*(2-1)! = 2*1! = 2
3! = 3(3-1)! = 3*2! = 3*2 = 6
4! = 4*(4-1)! = 4*3! = 24
4-6-2 递回的阶层函数-方法
04: static int factorial(int n)
05: { // 终止条件
06: if ( n == 1 ) return 1;
07: else return n * factorial(n-1);
08: }
4-6-3 河内塔问题-说明
「河内塔」(Tower of Hanoi)问题是程式语言在说明递回观念时,不可错过的实例,这是一个流传在Brahma庙内的游戏,庙内的僧侣相信完成这个游戏是一件不可能的任务.河内塔问题共有三根木桩,如下图所示:
4-6-3 河内塔问题-规则
共有n个盘子放置在第一根木桩,盘子的尺寸由上而下依序递增.河内塔问题是将所有的盘子从木桩1搬移到木桩3,在搬动的过程中有三项规则,如下所示:
每次只能移动一个盘子,而且只能从最上面的盘子搬动.
任何盘子可以搬到任何一根木桩.
必须维持盘子的大小是由上而下依序递增.
4-6-2 河内塔问题-步骤
归纳出三个步骤,如下所示:
Step 1:将最上面n-1个盘子从木桩1搬移到木桩2.
Step 2:将最后一个盘子从木桩1搬移到木桩3.
Step 3:将木桩2的n-1个盘子搬移到木桩3.
4-6-3 河内塔问题-方法
04: static void towerofHanoi(int dishs, int peg1,
05: int peg2, int peg3)
06: { if ( dishs == 1 ) { // 终止条件
07: System.out.print("盘子从" + peg1);
08: System.out.println("移到" + peg3);
09: }
10: else
11: { // 第一步骤
12: towerofHanoi(dishs-1, peg1, peg3, peg2);
13: System.out.print("盘子从" + peg1);
14: System.out.println("移到" + peg3);
15: // 第三步骤
16: towerofHanoi(dishs-1, peg2, peg1, peg3);
17: }
18: }
4-7 Math数学类别的类别方法
4-7-1 计算乱数,最大和最小值
4-7-2 Math类别的数学常数和方法
4-7 Math数学类别的类别方法
Java API的Math数学类别提供数学常数和各种数学函数的类别方法,我们可以在Java程式码使用乱数,计算最大值,最小值,三角和指数等数学函数,因为它是类别方法,在呼叫方法时需要指明类别Math.
4-7-1 计算乱数,最大和最小值
Math类别提供方法计算乱数,最大值和最小值.相关方法说明如下表所示:
4-7-2 Math类别的数学常数和方法-
常数
Math类别提供两个常用的数学常数,其说明如下表所示:
4-7-2 Math类别的数学常数和方法-
方法1
Math类别还提供三角函数(Trigonometic),指数(Exponential)和对数(Logarithmic)的方法.其相关方法说明如下表所示:
4-7-2 Math类别的数学常数和方法-
方法2
上表三角函数的参数是径度,并不是角度,如果是角度,请使用toRadians()方法先转换成径度.
End