Java入门(三)之方法的使用

方法的基本用法

什么是方法

方法就是一个代码片段。类似于 C 语言中的 “函数”。

方法存在的意义:

  1. 是能够模块化的组织代码(当代码规模比较复杂的时候)。
  2. 做到代码被重复使用, 一份代码可以在多个位置使用。
  3. 让代码更好理解更简单。
  4. 直接调用现有方法开发。
  5. 便于解耦。

固定写法

public static 返回值 方法名(形式参数){
    
    
    		方法体
}

例如:
在这里插入图片描述

运行如下
在这里插入图片描述
这就是较为简单的方法实现。
注意:

  1. Java当中的方法一定要写在类(class)里面的。
  2. 方法的名称一定是小驼峰型式(第一个单词以小写字母开始,第二个单词的首字母大写。例如:myAdd)。
  3. 有返回值,要写return(不写的话会报错);无返回值,可以不写。
  4. 方法运行在栈上。调用完毕栈帧销毁在这里插入图片描述
    5.类型和个数都要匹配,且一一对应。

我们来回顾下之前写过阶乘求和得例题
计算1!+2!+3!+4!+5!
用Java方法来写

public class TextDemo {
    
    
    public static int fac(int n) {
    
    
        /*
        这个方法的作用是计算n得阶乘
         */
        int ret = 1;
        for (int i = 1;i <= n; i++){
    
    
            ret *= i;
        }
        return ret;
    }

    public static int facSum(int num) {
    
    
        /*
        阶乘求和
         */
        int sum = 0;
        for (int i = 1;i <= num; i++){
    
    
            sum += fac(i);
        }
        return sum;
    }

    public static void main(String[] args) {
    
    
        int a = 5;
        System.out.println(facSum(a));
    }
}    	

运行结果如下
在这里插入图片描述

方法的定义语法

基本语法

// 方法定义
public static 方法返回值 方法名称([参数类型 形参 ...]){
    
    
方法体代码;
 [return 返回值];
}
// 方法调用
返回值变量 = 方法名称(实参...);

代码示例: 实现一个方法实现两个整数相加

public class TextDemo {
    
    
	 public static int myAdd(int a,int b) {
    
    
	        return a + b;
	    }
	}
	public static void main(String[] args) {
    
    
	        int a = 10;
	        int b = 20;
	        System.out.println(myAdd(a,b));
	    }
}

运行结果如下
在这里插入图片描述

  1. public和static两个关键字在此处具有特定含义, 我后面会为大家总结。
  2. 方法定义时,参数可以没有。每个参数要指定类型。
  3. 方法定义时,返回值也可以没有。如果没有返回值,则返回值类型应写成 void。
  4. 方法定义时的参数称为 “形参”,方法调用时的参数称为 “实参”。
  5. 方法的定义必须在类之中, 代码书写在调用位置的上方或者下方均可。
  6. 与C语言不同的是,Java 中没有 “函数声明” 这样的概念。

方法调用的执行过程

基本规则:

  1. 定义方法的时候,不会执行方法的代码。只有调用的时候才会执行。
  2. 当方法被调用的时候,会将实参赋值给形参。
  3. 参数传递完毕后,就会执行到方法体代码。
  4. 当方法执行完毕之后(遇到 return 语句),就执行完毕,回到方法调用位置继续往下执行。
  5. 一个方法可以被多次调用。

代码示例

public class TextDemo {
    
    
	public static void main(String[] args) {
    
    
		int a = 10;
		int b = 20;
		System.out.println("第一次调用方法之前");
		int ret = myAdd(a, b);
		System.out.println("第一次调用方法之后");
		System.out.println("ret = " + ret);
		System.out.println("第二次调用方法之前");
		ret = myAdd(30, 50);
		System.out.println("第二次调用方法之后");
		System.out.println("ret = " + ret);
	}
 
	public static int myAdd(int x, int y) {
    
    
		System.out.println("调用方法中 x = " + x + " y = " + y);
		return x + y;
	}
}

这段代码的运行结果如下
在这里插入图片描述

实参与形参的关系

在这里,我用Java方法来写交换两个整形数据。

public class TextDemo {
    
    
    public static void main(String[] args) {
    
    
        int a = 10 ;
        int b = 20 ;
        System.out.println(a + "  " + b);
        mySwap(a ,b);
        System.out.println(a + "  " + b);

    }

    public static void mySwap(int a ,int b){
    
    
        int temp = a;
        a = b;
        b = temp;
        return ;
    }
}

运行结果如下
在这里插入图片描述
我们发现,实参的 a ,b并没有实现数据交换。这和代码只是交换了mySwap方法的 a, b 数据,对main方法的 a ,b 并没有发生改变。与C最大的不同就是,C可以通过指针来实现对主函数,两个数据的交换。Java中,栈上的内存地址是无法得到。
目前,要想实现对主方法两个数据实现交换,需要把 a , b 放到堆上。
在这里插入图片描述

正确代码如下

public class TextDemo {
    
    
    public static void main(String[] args) {
    
    
        int[] array = {
    
    10,20};//此时10,20就是存放在堆上的。(数组是对象 )
        System.out.println("交换前打印");
        System.out.println(array[0] + " " + array[1]);
        mySwap(array);
        System.out.println("交换后打印");
        System.out.println(array[0] + " " + array[1]);
        //System.out.println(array);
    }
    public static void mySwap(int[] array2){
    
    
        int temp = array2[0];
        array2[0] = array2[1];
        array2[1] = temp;
    }
}

运行结果如下

在这里插入图片描述

通过引用数组对象,从而实现了交换数据。
需要补充的是,Java中的数组,与C有很大的区别。数组是在栈帧上开辟的,但是数组引用的对象,是在堆区的。而数组名只存放了该数组的地址。
在这里插入图片描述

无返回值的方法

方法的返回值是可选的,有些时候可以没有的。
见代码

public class TextDemo {
    
    
    public static void main(String[] args) {
    
    
        int a = 10;
        int b = 20;
        print(a, b);
    }
    public static void print(int x, int y) {
    
    
        System.out.println("x = " + x + " y = " + y);
    }
}

运行结果如下
在这里插入图片描述
可见,当我们不需要返回值时,方法的关键字用void,且方法中不需要return。

方法的重载

有些时候我们需要用一个函数同时兼容多种参数的情况,我们就可以使用到方法重载。
区别 重载 和 重写(覆盖/覆写)。
重载(overload)前提是在一个类之中,满足三个条件:

  1. 方法名称相同
  2. 参数列表不同(类型&个数)
  3. 返回值不做要求
    上代码
    在这里插入图片描述
    运行结果如下
    在这里插入图片描述
    此时,我们发现sub方法出现两个可选项,且一个选项为整数减法,一个选项为小数减法,这就是方法的重载。
    在这里插入图片描述

重写(override) 需要学习Java多态相关知识之后,总结什么是重写。

注意:当两个方法的名字相同,参数也相同,但是返回值不同的时候,不构成重载。
当需要重载的方法。其参数个数未知时,可以使用如下方法。

public static int sub(int...array){
    
    
}

在这里插入图片描述
运行结果如下
在这里插入图片描述

方法递归

递归:将大问题化解为小问题,处理大问题和处理小问题的方式是一样的。且有递归的递推公式。
递归前提:

  1. 有一个趋近于终止的条件。
  2. 调用自己本身。

对于递归来说,可以看作是有两步,先递后归。
例如,求5的阶乘

public class TextDemo {
    
    
    public static void main(String[] args) {
    
    
        System.out.println(myFac(5));
    }
    public static int myFac(int n){
    
    
        if (n == 1){
    
    
            return 1;
        }
        int temp = n * myFac(n-1);
        return temp;
    }
}

运行结果如下
在这里插入图片描述

递归小结:

  1. 递归是一种重要的编程解决问题的方式。
  2. 有些问题天然就是使用递归方式定义的(例如斐波那契数列, 二叉树等),此时使用递归来解就很容易。
  3. 有些问题使用递归和使用非递归(循环)都可以解决,那么此时更推荐使用循环,相比于递归,非递归程序更加高效。

递归例题
一.求斐波那契数列的第n项
上代码

import java.util.Scanner;

public class TextDemo {
    
    
    public static void main(String[] args) {
    
    
        Scanner scanner = new Scanner(System.in);
        System.out.println("你想求斐波那契数列的第几项?");
        int num = scanner.nextInt();
        System.out.println(fib(num));
    }
    public static int fib(int i){
    
    
        if ((i == 1)||(i == 2)){
    
    
            return 1;
        }else {
    
    
            return  fib(i-1) + fib(i-2);
        }

    }
}

运行结果如下
在这里插入图片描述

我们发现如果要求fib(40),虽然程序可以执行,但是耗费较长时间。此时,推荐使用循环结构也称迭代(基本秒出结果),从而避免出现冗余运算。

代码如下

import java.util.Scanner;

public class TextDemo {
    
    
    public static void main(String[] args) {
    
    
        Scanner scanner = new Scanner(System.in);
        System.out.println("你想求斐波那契数列的第几项?");
        int num = scanner.nextInt();
        System.out.println(myFib(num));
    }

    public static int myFib(int n) {
    
    
        int f1 = 1;
        int f2 = 1;
        int f3 = 0;
        for (int i = 3; i <= n; i++) {
    
    
            f3 = f1 + f2;
            f1 = f2;
            f2 = f3;
        }
        return cur;
    }
}

运行结果如下
在这里插入图片描述
二.求解汉诺塔问题
题目背景:汉诺塔问题是一个经典的问题。汉诺塔(Hanoi Tower),又称河内塔,源于印度一个古老传说。大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。并且规定,任何时候,在小圆盘上都不能放大圆盘,且在三根柱子之间一次只能移动一个圆盘。问应该如何操作?
代码如下

import java.util.Scanner;

public class TextDemo {
    
    
    public static void main(String[] args) {
    
    
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入盘子的个数");
        int num = scanner.nextInt();
        hanota(num,"a","b","c");
    }
    public static void hanota(int n,String a,String b,String c){
    
    
        if (n == 1){
    
    
            System.out.println(a + "=>" +c);
        }else {
    
    
            hanota(n-1, a , c , b );
            System.out.println(a + "=>" +c);
            hanota(n-1, b , a , c );
        }
    }
}

运行结果如下
在这里插入图片描述
是否各位铁铁还记得,看《猩球崛起》时,研究人员就是用汉诺塔来检测猩猩们的智商。上面就是通过使用Java方法递归来实现。

三.青蛙跳台阶问题
一只青蛙一次可以跳上 1 级台阶,也可以跳上2 级。求该青蛙跳上一个n 级的台阶总共有多少种跳法。

台阶级数 可跳方法
1 1
2 2
3 3
4 5
5 8
6 13

我们可以从中找出规律。
Java通过方法递归实现如下

import java.util.Scanner;

public class TextDemo {
    
    
    public static void main(String[] args) {
    
    
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入台阶数");
        int num = scanner.nextInt();
        System.out.println(jump(num));
    }
    public static int jump(int i){
    
    
        if (i == 1 ){
    
    
            return 1;//只有一个台阶,只有一种跳法
        }else if (i == 2){
    
    
            return 2;//有两个台阶,有两种跳法:先跳1再跳1,或者直接跳2.
        }
        else {
    
    
            return jump( i -1) + jump( i - 2);
            /*
            当有num个台阶时,有(num - 1)+(num - 2)种跳法
            1.青蛙第一次跳一个台阶,剩下的台阶有(num - 1)种跳法
            2.青蛙第一次跳两个台阶,剩下的台阶有(num - 2)种跳法
            这是数学问题,
             */
        }
    }

运行结果如下

在这里插入图片描述
各位铁铁,Java入门(三)之方法的使用到这里就结束了。感谢大家的浏览和点赞,下期将为大家带来数组的定义和使用,我们下期见。

猜你喜欢

转载自blog.csdn.net/Kaiiiiiiiiiiiiii/article/details/112382085