1、什么是方法?
方法就是一个代码片段,类似于c语言中的函数(就是把一段{}代码抽出来的片段)
2、方法存在的意义(理解记忆)
(1)能够模块化的组织代码(当代码规模比较复杂的时候)
(2)做到代码被重复使用,一份代码可以在多个位置使用(复用性,已经写好的代码块,可以被重复利用多次,这个时候就可以把这段代码抽象成方法)比如:判断一个正整数是否是素数就是一个典型的会被利用多次的代码块,应该定义成方法
(3)让代码更好理解,更加简单
(4)直接调用现有方法开发,不必重复造轮子。
3、方法定义的语法
public static 方法返回值 方法名称(方法的参数…[0…N]){
//方法体代码
[return]语句;//该方法是否有返回值,要看这个方法他的作用或者功能是啥,比如求某几个数的和(int),现在调用方法就是想知道这几个数的和是多少,当然有返回值告知调用者返回值是多少 --> 返回int
}
4、方法的调用:返回值变量 = 方法名称(参数);小案例:定义一个方法,实现两个int相加
public class functest { public static void main(String[] args) { int x = 10;//实参 int y = 20;//实参 int sum = add(x,y);//主方法走到第三行时,就会暂停执行,直到add方法调用结束(碰到return语句) System.out.println("sum的值为:" + sum); } public static int add(int a ,int b){//此时定义的a和b为形参 int ret = a + b; return ret; } }
注意事项:
(1)public和static两个关键字在此处具有特定含义,我们暂时不讨论,后面会详细介绍
(2)方法定义时,参数可以没有,每个参数要指定类型
(3)方法定义时,返回值也可以没有,如果没有返回值,则返回类型应该写成void
(4)方法定义时的参数称为"形参",方法调用时的函数称为“实参”
(5)方法的定义必须在类之中,代码书写在调用位置的上方或者下方均可
(6)Java中没有“函数声明”这样的概念,只有方法的名称和参数,没有具体的实现这个是不可以的
5、方法调用的执行过程:
基本规则:
(1)当定义方法的时候,不会执行方法的代码,只有调用的时候才会执行
(2)当放大被调用的时候,会将实参赋值给形参
(3)参数传递完毕后,就会执行到方法体代码
(4)当方法执行完毕之后(遇到return语句),就执行完毕,回到方法调用的位置继续向下执行
(5)一个方法可以被多次调用,示例如下:
public class functest { public static void main(String[] args) { System.out.println("第一次调用方法之前"); int x = 10; int y = 20; int sum = add(x,y); System.out.println("第一次调用方法之后"); System.out.println("sum的值为:" + sum); System.out.println("第二次调用方法之前"); sum = add(20,40); System.out.println("第二次调用方法之后"); System.out.println(sum); } public static int add(int a ,int b){ int ret = a + b; return ret; } }
关于实参与形参的关系(重点!!!) :在Java中,方法的参数传递只有值传递,所谓的值传递就是把实参的值拷贝一份拿给形参,对实参没有任何的影响 案例如下:
public class swaptest { public static void main(String[] args) { int x = 10; int y = 20; swap(x,y);//将x的值10和y的值20拿出来复制一份传递给a和b,调用swap方法时,x和y是主方法中的x和y,实参 System.out.println("x ="+ x + ",y =" + y); } public static void swap(int a,int b){ //调用swap时,就有实参到形参的传递,将实参的值拷贝一份赋值给形参 swap-a = main-x =10;swap-b = main-y =20; int temp = a;//temp = 10; a = b;// a = 20; b = temp;//b = 10; //交换的是swap-a和swap-b,对main-x和main-y不造成任何影响 System.out.println("a ="+ a + ",b =" + b); } }
那么如何进行解决呢?要知道,在方法外部交换两个局部变量的场景在Java中压根不存在,这个问题的解决需要引入引用数据类型(数组或对象)
public class swaptest { public static void main(String[] args) { // int x = 10; // int y = 20; // swap(x,y); // System.out.println("x ="+ x + ",y =" + y); int[] arr = {10,20};//通过引入引用数据类型加以解决 swapArr(arr); System.out.println("arr[0] =" + arr[0] +",arr[1] = " +arr[1]); } public static void swapArr(int[] arr){ int temp = arr [0]; arr [0] = arr [1]; arr [1] = temp; } }
方法的返回值可有可无,没有返回值的方法使用void声明,在没有返回值的方法中,仍然可以使用return;表示提前结束方法的调用。示例如下:
public class swaptest { public static void main(String[] args) { printNum(100); } //传入一个num,输出一个从1开始到num的3的倍数 public static void printNum(int num){ for (int i = 1; i <= num; i++) { if (i % 3 == 0){ System.out.println(i); //直接终止本次方法的调用,返回调用处继续执行。 return; } } } }
6、关于方法的重载:
方法的重载发生在”同一个类中“,定义了若干个方法名称相同,参数列表不同(参数的类型或者个数不同)的一组方法,与返回值无关!!这样的一组方法称为重载方法,案例如下:
public static int add(int a ,int b){ int ret = a + b; return ret; } //因为此时我们就是在进行两个参数的相加,所有相同功能的方法我们要定义为相同的参数名称 //最大程度减少用户的学习成本 public static double add(double a,double b){ //与上面的add方法相比较,参数类型不同 return a + b; } public static int add(int a, int b, int c){ //与上面的add方法相比较,参数的个数不同 return a + b +c; }
再比如,Java中的输出语句,任意参数类型都可以,实际上就是System这个类中定义了N个重载方法
易错点:示例如下
public static int add(int a ,int b){ int ret = a + b; return ret; } //这里不是重载方法,因为返回值的类型不同,会显示'add(int,int)' is already defined in'functest' public static double add(int a,int b){ //与上面的add方法相比较,参数类型不同 return a + b; }
7.方法的递归
注意:目前只是引出方法递归,能独立写出递归代码需要时间和代码的累积,并不是一蹴而就的,方法递归在后面学习的数据结构和算法方面是一个必须掌握的金额呢过
(1)什么是方法递归?
所谓方法递归就是在一个方法执行的内部,自己调用自己的过程,称之为递归,例如public static void test(){ tese(); } 递归分为两个子过程,递过程:函数不断调用自身,直到走到函数的终止条件,第一阶段结束。归过程:函数不断返回的过程称为归过程。
(2)什么场景下能用方法递归?
a.一个大问题可以拆分成若干个子问题的解
b.拆分后的子问题和原问题除了数据规模不同,解决思路完全相同
c.必须存在递归的终止条件(不会无限拆分下去,一定能走到根儿)
那么,到底如何写出递归代码?
在写递归函数时,千万不要纠结这个函数内部到底咋实现,而要注意这个方法的语义(这个函数到底有什么功能),你就假设,这个方法别人已经写好了,你只是调用这个方法而已。
例如:求一个整数num的阶乘 public static int factor(int num){}, 这个问题就是求一个数num的阶乘问题---->需要先进行拆分,54的阶乘值,再拆分为54*3的阶乘值,一直拆分到某个子问题时,无法再次拆分,这个子问题就是这个递归的终止条件。
总结:写出递归代码其实=终止条件+不借助任何方法就能实现的步骤+剩下的问题利用这个方法去解决
一些关于递归的小练习:
public static void main(String[] args) { //案例1:传入一个整数num,可求出num的阶乘值 Scanner scanner = new Scanner(System.in); System.out.println("请输入要求的阶乘数"); int num = scanner.nextInt(); System.out.println(factor(num)); } public static int factor(int num){ //1、终止条件,当求1的阶乘时可以直接得出结果 if (num == 1 ){ return 1; } //2、当num>=2时 return num * factor(num-1); }
public static void main(String[] args) { //案例2:求1729各个位数的和 = 1+7+2+9 = 19 System.out.println(add(1729)); } public static int add(int num){ //1、终止条件,当num为个位时,可以直接获取结果 if (num < 10){ return num; } //2、num此时至少是个十位数,知道个位是几,但剩下的不知道,除个位外其他数之和+个位数 就是整个问题的解 return num % 10 + add(num / 10); }
总结:什么是终止条件?
所谓终止条件就是不借助任何函数就能直接知道答案的值,当num是个位数时,组成她的位数只有自己,二num至少为十位数时,对于任意整数而言,这个正整数位数多少未知,至少是个两位数,我们怎么可能知道?所以,我管你是几位数,我一定知道你的个位数时多少!!!num % 10 剩下的位数和怎么办?交给别人整,我整不了