• 【JavaSE】函数or方法?方法的重载讲解


    什么是方法

    在C语言的学习中我们学习到了一个概念叫做函数,那么在Java的语法中有没有类似函数的东西的,答案是有的,但是在Java的语法中不叫函数,我们成为方法。什么是方法呢?我们通过一段代码来体会一下方法:

        public static int add(int x,int y ) {
            return x + y;
        }
    
        public static void main(String[] args) {
            int x = 10;
            int y = 20;
            int z = add(x,y);
            System.out.println(z);
    
            int a = add(1,44);
            System.out.println(a);
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    上面的代码我们就定义了一个可以实现两个数相加方法,这样看这个方法的作用不是很明显,因为方法中完成的功能十分简单,如果功能十分复杂并且在项目中这个功能被使用多次,难道每次使用我们都要重新写一遍码?我们可以把这个功能用方法模块化起来,每次使用只需要调用方法就可以了。所以总结一下方法的功能:

    1、当一个功能十分复杂时,方法可以模块化的组织代码
    2、方法可以做到让代码重复使用,在多个位置使用
    3、让代码更好理解
    4、直接调用现有的开发方法,不需要重复造轮子。

    如何定义方法

    好了我们知道了什么是方法之后,我们该如何在自己的代码中使用方法呢?让我来告诉大家:

    方法的语法格式
    访问修饰符 返回值类型 方法名称 (参数类型 形参…) {
    方法体代码;
    return 返回值;
    }

    使用这样的语法我们就可以在我们的代码中定义一个方法,让我们来尝试写一个求两个数的较大值的方法吧:

      public static int max(int x,int y) {
            return x > y ? x : y;
        }
    
    • 1
    • 2
    • 3

    这样我们就写了一个求最大值的方法,我么来对这个方法分析一下:

    public static :访问修饰符,现阶段直接使用public static 固定搭配
    int :返回值类型
    max:函数的名字
    (int x , int y): 形参
    return x > y ? x : y;:返回值
    花括号里面的就是方法体

    方法写完了,我们该如何使用方法呢?定义方法的时候方法不会执行的,只有我们调用的时候方法才会被执行,并且方法可以被多次调用

    方法名(参数类型 实参…)

    我们来调用一下我们的方法:

      public static int max(int x,int y) {
            return x > y ? x : y;
        }
    
        public static void main(String[] args) {
            int max = max(5,8);
            System.out.println("第一次调用:" + max);
            int max2 = max(10,50);
            System.out.println("第二次调用:" + max2);
        }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    在这里插入图片描述
    上面就是我们执行的结果。

    方法的调用过程

    我们先来大致的说一下方法的调用过程,我们调用方法 - > 传递参数 - > 找到方法的地址 - > 执行被调用方法的方法体 - > 被调用的方法结束返回 - > 回到主方法继续执行
    我们先写一个简单的代码:

     public static int add(int x , int y) {
            return x + y ;
        }
    
        public static void main(String[] args) {
            int a = 10;
            int b = 20;
            int num = add(a,b);
            System.out.println(num);
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    那么这个方法是如何被调用的呢?我们通过画图来向大家解释:
    在这里插入图片描述

    最后当add方法结束后,在栈上为add方法开辟的空间会被回收,之后返回主方法继续执行,当主方法执行完毕,主方法的空间也会被回收。

    形参与实参的关系

    我们来看一段代码:

       public static void swap(int x ,int y) {
            int tmp = x;
            x = y;
            y = tmp;
        }
        
        public static void main(String[] args) {
            int a = 10;
            int b = 20;
            swap(a,b);
            System.out.println(a);
            System.out.println(b);
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    这个swap方法会不会把交换a和b两个变量的值呢?我们执行以下看看结果
    在这里插入图片描述
    答案是并没有,原因是什么呢?在上面我们介绍了方法调用的过程,我们知道了在调用时swap方法和main方法各自开辟属于各自的栈帧,ab变量在main函数所在的栈帧中,而xy在swap所在的栈帧中,ab变量和xy变量,没有任何关系,所以我们交换了xy并不会对ab的值造成任何影响。总结以下:在swap方法调用时,只是将实参a和b中的值拷贝了一份传递给了形参x和y,因此对形参x和y操作不会对实参a和b产生任何影响

    方法的重载

    为什么要重载

    先让我们来看一个例子吧,还是求两个数相加的方法

      public static int add(int x,int y ) {
            return x + y;
        }
    
        public static void main(String[] args) {
            int a = 10;
            int b = 20;
            double c = 10.3;
            double d = 9.9;
            int e = add(a,b);
            System.out.println(e);
            
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    现在我写了一个返回值类型为int参数类型为int ,int的方法,但是现在两个int类型的变量相加我们可以使用这个add方法,如果我们有两个double类型的变量,就不可以使用add方法了,有一个非常简单粗暴的方法,就是我们再写一个方法。

        public static int add(int x,int y ) {
            return x + y;
        }
    
        public static double add_double(double x,double y) {
            return x + y;
        }
        public static void main(String[] args) {
            int a = 10;
            int b = 20;
            double c = 10.3;
            double d = 9.9;
            int e = add(a,b);
            System.out.println(e);
            double f = add_double(c,d);
            System.out.println(f);
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    在这里插入图片描述
    上面的代码解决了问题,但是我们需要提供许多不同的方法名,而取名字本来就很让人头疼,我们是否可以将所有名字都写成add呢?这时就要使用到我们的方法重载了。

    重载的概念

    在我们的日常生活中,经常会出现一词多义的现象,例如:你的女朋友对你说你是个好人和你帮助他人时,别人对你说的你是个好人,所代表含义是不一样的。出现这样的情况我们就可以说该词被重载了。在Java中,如果多个方法的名字相同,参数列表不同,则称该种方法被重载了

        public static int addNum(int x ,int y) {
            return x + y;
        }
        
        public static double addNum(double x ,double y) {
            return x + y;
        }
        
        public static int addNum(int x ,int y ,int z) {
            return x + y + z;
        }
        
        public static double addNum( double x , int y ) {
            return x + y; 
        }
    
        public static void main(String[] args) {
            int a =addNum(10,20);
            double b = addNum(10.4,2.5);
            double c = addNum(10.4,5);
            int d = addNum(10,20,30);
            System.out.println(a);
            System.out.println(b);
            System.out.println(c);
            System.out.println(d);
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    上面这个代码演示了Java中方法的重载,有些地方值得我们注意:

    1、重载时方法名必须相同
    2、参数列表必须不同(参数的个数、类型、次序不同)
    3、与返回值类型是否相同无关
    4、编译器在编译代码时,会对形参类型进行推演,根据推演的结果来确定调用哪个方法

    在这里插入图片描述
    这样写是不行的,因为重载与返回值类型是否相同无关。有点同学会想到了,我们把名字都写成一样的化,如果这个方法重载了很多次我记不住自己写了那些方法怎么办呢?我们的IDEA非常的聪明,会在我们调用方法时给出我们提示:
    在这里插入图片描述

    方法签名

    有些兄弟在看完重载后会产生一些疑问,为什么在方法内定义变量,不可以定义两个名字一样的变量,在类中的方法就可以定义两个一模一样名字的方法呢?这就要提到方法签名了,在经过编译器编译修改之后的方法最终的名字我们成为方法签名。
    具体方式方法全路径名 + 参数列表 + 返回值类型构成方法完整的名字。

    我们可以在编译过后,使用JDK自带的javap反汇编工具查看方法签名:

    1、先对工程进行编译,生成.class字节码文件
    2、在控制台中进入到.class所在的目录
    3、输入java -v 字节码文件名即可

    在这里插入图片描述

    递归

    在C语言函数部分的学习中,我们也曾提到递归的概念,简单来说就是一个函数自己调用自己,我们就称为递归,那么我们就可以类比出,在Java中的递归就是方法自己调用自己。对递归的概念不太熟悉的可以去看看博主的这篇文章:函数的递归
    我们通过一道练习题来感受如何使用Java实现递归吧,我们使用递归求n的阶乘

     public static int getNum(int x ) {
            if(x == 1) {
                return 1;
            }
            return x * getNum(x - 1);
        }
    
        public static void main(String[] args) {
            int num = getNum(5);
            System.out.println(num);
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    这样我们就完成了题目,是不是跟C语言中的递归方式一样呢。最后总结一下递归的两个必要条件吧:

    1、需要有递归的出口,上面代码当形参等于 1 时 就是递归的出口
    2、将原问题划分成其子问题,注意:子问题必须要与原问题的解法相同

    递归还有一些经典例题,例如汉诺塔问题,他家可以看看我的这篇文章:经典递归问题汉诺塔 这篇文章使用的C语言完成了汉诺塔问题,大家可以尝试着使用Java实现一下。

  • 相关阅读:
    jvm之jvm基础
    19-Mitt
    好用的记笔记app选哪个?
    【集合】- ArrayList源码分析
    HMS Core助力宝宝巴士为全球开发者展现高品质儿童数字内容
    Kafka为什么这么快?
    解决Tomcat启动后的控制台乱码问题
    C# 中的类、结构和记录概述
    自用软件分享,这有几款实用软件
    IOS Swift 从入门到精通:@escaping 和PreferenceKey
  • 原文地址:https://blog.csdn.net/weixin_64182409/article/details/127681812