方法_详析

方法
  1. 方法概念:实现特定功能的一段代码,可反复使用

  2. 定义语法:

    ​ public static void 方法名称(){

    ​ //方法主体

    }

  3. 经验:将需要多个位置重复使用的一组代码,定义在方法内部

  4. 定义的位置:

    //位置1
    public class TestDefinitionFunction {
        //位置2
        public static void main(String[] args) {
            //位置3
     }
        //位置4
    }
    //位置5
    

    正确位置:位置2,位置4

  5. 定义的一个方法

    public class TestFunction {
        public static void main(String[] args) {
            System.out.println("窗前明月光");
            printSign();
            System.out.println("疑是地上霜");
            printSign();
            System.out.println("举头望明月");
            printSign();
            System.out.println("低头思故乡");
            printSign();
        }
        
        //定义:打印10个分隔符的函数
        public static void printSign() {
            for(int i = 1;i <= 10;i++) {
                System.out.print("-");
            }
            System.out.println();
        }
    }
    

    注:在需要执行方法代码的位置,通过方法名称进行调用

    ​ 调用方法时,会优先执行方法内部代码,结束后,返回方法调用处,继续向下执行

  6. 方法的参数

    多数的情况下,方法与调用者之间需要数据的交互,调用者必须提供必要的数据,才能使方法完成相应的功能

    调用方法时,所传入的数据被称为“参数”

  7. 形参与实参

    定义语法:

    ​ public static void 方法名称(形式参数) {

    ​ //方法主体

    }

    经验:“形参”等价于“局部变量的声明”

    调用语法:

    方法名称(实际参数);

    经验:“实参”等价于“局部变量的赋值”

    作用:方法的参数可以让代码功能更灵活、普适性更高、易于修改及维护

  8. 单个参数

    public class TestFunction {
        public static void main(String[] args) {
            System.out.println("窗前明月光");
            printSign(10);
            System.out.println("疑是地上霜");
            System.out.println("举头望明月");
            System.out.println("低头思故乡");
        }
        
        //定义:打印count个分隔符的函数
        public static void printSign(int count) {
            for(int i = 1;i <= count;i++) {
                System.out.print("-");
            }
            System.out.println();
        }
    }
        }
    }
    

    代码分析:

    ​ 实际参数:10

    ​ 调用带参数方法时,必须传入实际参数,为形式参数赋值

    ​ 形式参数: int count

    ​ 当方法被执行时,循环count次

  9. 多个参数

    public class TestFunction {
        public static void main(String[] args) {
            System.out.println("窗前明月光");
            printSign(10 ,'#');
            System.out.println("疑是地上霜");
            System.out.println("举头望明月");
            System.out.println("低头思故乡");
        }
        
        //定义:打印count个sign的函数
        public static void printSign(int count,char sign) {
            for(int i = 1;i <= count;i++) {
                System.out.print(sign);
            }
            System.out.println();
        }
    }
        }
    }
    

    代码分析:

    ​ 实参:10,#

    ​ 调用带参方法时,依次传入实参

    ​ 类型、个数、顺序必须与形参对应

    ​ 形参:int count,char sign

    ​ 当方法被执行时,打印count次sign

  10. 如何定义参数

    经验:根据具体的业务需求,来定义方法的参数

  11. 返回值与返回值类型

    概念:方法执行后的返回结果

    注意:方法执行后,一些情况下无需返回结果;另一些情况下则必须返回结果

    例如:

    ​ 存款操作无需返回结果;

    ​ 取款操作必须返回结果;

    定义语法:

    ​ public static 返回值类型 方法名称(形式参数列表){

    ​ //方法主体

    ​ return value;//返回值

    }

    注:

    ​ 返回值类型:规定返回值的具体类型(基本、引用、void)

    ​ return value:根据需求返回一个结果(值)

​ 调用语法:

​ 变量 = 方法名称();

  1. 代码练习:

    需求:定义方法,计算两个整数的和,并返回结果,在main中打印

    public class TestResultValue {
        public static void main(String[] args) {
            int result = add(5,6);
            System.out.println(result);
        }
        public static int add(int a,int b) {
            return a + b;
        }
    }
    

    add( 5, 6 ) : 接收返回值(方法调用的表达式,最终即代表了所返回的结果)

    int : 返回值类型(定义时,即约定了返回的结果类型)

    return a + b : 返回值(与返回值类型匹配的具体结果,在return关键字的后面追加具体值)

  2. return关键字

    public static TestResultValue {
        public static void main(String[] args) {
            System.out.println("两值的和:" + calc(6,8));
            System.out.println("两值的差:" + calc(5,2));
            
            public static int calc(int a,int b) {
                
                return a + b;
                return a - b;//错误:一个方法只能有一个返回值
            }
        }
    }
    
    public class TestResultItValue {
        public static void main(String[] args) {
            String result = isEven(10);
            System.out.println(result);
        }
        
        public static String isEven(int num) {
            if(num % 2 == 0) {
                return "偶数";
            }else {
                return ""奇数;
            }
        }
    }
    

    注:当有返回值的方法存在分支结构时。必须保证每一条分支都具有正确的返回值

    return的两种用法:

    ​ 应用在具有返回值类型的方法中:

    ​ return value;//表示结束当前方法,并伴有返回值,返回到方法调用处

    应用在没有返回值的类型(void)的方法中:

    ​ return;//表示结束当前方法,直接返回方法调用处

    public static void show() {
        for(int i = 1;i <= 100;i++) {
            if(i == 50) {
                
                return;//结束当前方法直接返回
            }
        }
    }
    
    

#### 小结

注意:一个类中可以定义多个方法,方法之间属于并列关系,不可嵌套

经验:一个方法只做一件事

优点:

  1. 减少代码冗余

  2. 提高复用性

  3. 提高可读性

  4. 提高可维护性

 	5. 方便分工合作

14. 多级调用

    ```java
    public class TestNestInvoke {
        public static void main(String args) {
            m1;//1.执行
        }
        public static void m1() {//2. 执行
            System.out.println("m1() - start");
            m2();//3. 执行
            System.out.println("m1() - end");
        }
        public static void m2() {//4. 执行
            System.out.println("m2() - start");
            System.out.println("m2() - end");
        }
    } 
    ```

    运行结果:

    ​				m1() - start

    ​				m2() - start

    ​				m1() - end

    ​				m2() - end

    优先执行方法内部代码,结束后,返回到调用处,继续向下执行

15. 无穷递归

    ```java
    public class TestRecursionInvoke {
        public static void main(String[] args) {
            m1;
        }
        
        public static void m1() {
            System.out.println("m1() - start");
            m1();
            System.out.println("n1() - end");
        }
    }
    ```

    运行结果:

    ​				m1() - start

    ​				m1() - start......

    当方法自己调用自己时,如果没有正确的出口条件,则产生无穷递归。

    Exception in thread "main" java.lang.StackOverflowError  内存溢出

16. 递归

    什么是递归?

    解决具有既定规律的问题时,在方法内部再次调用自身方法的一种编程方式

    何时使用递归?

    当需要解决的问题可以拆分成若干小问题,大小问题的解决方式相同,方法中自己调用自己

    使用循环解决的常规问题,都可以替换为递归解决

    如何正确使用递归?

    设置有效的出口条件,可以让调用链上每个方法都可以正确返回,避免无穷递归

    

17. 循环阶乘

    计算5的阶乘:5! = 5 * 4 * 3 * 2 * 1;

    ```java
    public class TestFactorial {
        public static void main(String[] args) {
            System.out.println(factorial(5));
        }
        
        public static int factorial(int n) {
            int sum = 1;
            for(int i = 2;i <= n; i++) {
                sum *= i;
            }
            return sum;
        }
    }
    ```

    

18. 递归阶乘

    阶乘的定义:n! = n * (n - 1) * (n - 2) *(n - 3)......
    
    5! = 5 * 4! = 120
    
    ​	4! = 4 * 3! = 24
    
    ​		3! = 3 * 2! = 6
    
    ​			2! = 2 * 1! = 2
    
    ​				1! = 1(1的阶乘就是1)

递进:每一次推进,计算都比上一次变得简单,直至简单到无需继续推进,就能获得结果。也叫到达出口。

回归:基于出口的结果,逐层向上递归,依次计算每一层的结果,直至回归到最顶层。

代码练习:

```java
public class TestFactorial {
    public static void main(String[] args) {
        System.out.println(getFive(5));
    }
    public static int getFive(int n) {//n = 5
        
        return n * getFour(n - 1);    //5 * 4!
        
    }
    public static int getFour(int n) {//n = 4
    
    	return n * getThree(n - 1);   //4 * 3!
            
        }
    public static int getThree(int n) {//n = 3
    
    	return n * getTwo(n -1);       //3 * 2!
            
        }  
    public static int getTwo(int n) {  //n = 2
    
    	return n * getOne(n -1);       //2 * 1!
            
        }   
    public static int getOne(int n) {  //n = 1
    
    	return 1;                     //1! = 1
            
        }   
    }
}

多个方法解决问题的思路相同,同时遵循着相同的规律。如何整合成为一个方法?

public class TestFactorial {
    public static void main(String[] args) {
        System.out.println(factorial(5));
    }
    
    public static int factorial(int n) {
        return n * factorial(n - 1);
    }
}

当n = 1时并没有计算出1! = 1而是继续递进,计算1! = 1 * 0,所以导致永远没有出口条件,则造成无穷递归,内存溢出

Exception in thread “main” java.lang.StackOverflowError 内存溢出

增加出口条件,n = 1时,无需计算阶乘,直接返回结果1

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

注意:所有能以递归解决的问题,循环都可以解决。当解决复杂问题时,递归的实现方式更为简单。

课堂案例:

使用递归完成“斐波那契数列”

0  1 1 2 3 5 8 13 21 34 55......
总结
  1. 方法的概念:实现特定功能的一段代码,可以反复使用

  2. 方法的组成:

    ​ public static 返回值类型 方法名(形参列表…) {

    ​ 方法主体

    ​ [return 返回值]

    }

  3. 方法的调用:

    方法名(实参列表…)

  4. 方法的好处:

    ​ 减少冗余、提高复写性、可读性、可维护性、方便分工合作

  5. 递归:

    ​ 将大问题拆分为若干个小问题,大小问题的解决方法相同,有固定规律,需设置有效的出口条件,方法中自己调用自己。

作业
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值