day10_方法的重载(overload)丶可变形参丶方法参数的值传递机制丶递归

方法的重载(overload)

概念:同一个类中,允许存在一个以上的同名方法,只要它们的参数个数或者参数 类型不同即可修饰符和返回值类型无关。

参数列表不同是指:

  • 个数不同
  • 数据类型不同
  • 顺序不同。

重载的特点:

  • 返回值类型无关,只看参数列表,且参数列表必须不同。(参数个数或参数类型)。

重载方法调用

  • JVM通过方法的参数列表,调用不同的方法。 

举例:

/*
 * 方法的重载(overload)  loading...
 *
 * 1.定义:在同一个类中,允许存在一个以上的同名方法,只要它们的参数个数或者参数类型不同即可。
 *
 *  "两同一不同":同一个类、相同方法名.参数列表不同:参数个数不同,参数类型不同
 *
 *
 * 判断是否是重载:
 *    跟方法的权限修饰符、返回值类型、形参变量名、方法体都没有关系!
 *
 * 在通过对象调用方法时,如何确定某一个指定的方法:
 *      方法名 ---> 参数列表
 */
public class OverLoadTest {
    public static void main(String[] args) {

        OverLoadTest test = new OverLoadTest();
        test.getSum(1, 2);


    }

    //如下的4个方法构成了重载
    public void getSum(int i, int j) {
        System.out.println("1");
    }

    public void getSum(double d1, double d2) {
        System.out.println("2");
    }

    public void getSum(String s, int i) {
        System.out.println("3");
    }

    public void getSum(int i, String s) {
        System.out.println("4");
    }


}

 使用重载方法,可以为编程带来方便。 例如,System.out.println()方法就是典型的重载方法。

 
/*
 * 1.编写程序,定义三个重载方法max(),
	第一个方法求两个int值中的最大值,
	第二个方法求两个double值中的最大值,
	第三个方法求三个double值中的最大值,
 */
public class OverloadExer {
 
    //2.如下的三个方法构成重载
    public int max(int i, int j) {
        return (i > j) ? i : j;
    }
 
    public double max(double d1, double d2) {
        return (d1 > d2) ? d1 : d2;
    }
 
    public double max(double d1, double d2, double d3) {
        double max = (d1 > d2) ? d1 : d2;
        return (max > d3) ? max : d3;
    }
}

可变个数的形参

在JDK1.5之后,如果我们定义一个方法需要接受多个参数,并且多个参数类型一致,我们可以对其简化成如下格式:

                                         

JDK1.5以后。出现了简化操作。... 用在参数上,称之为可变参数。同样是代表数组,但是在调用这个带有可变参数的方法时,不用创建数组(这就是简单之处),直接将数组中的元素作为实际参数进行传递,其实编译成的class文件,将这些元素先封装到一个数组中,在进行传递。这些动作都在编译.class文件时,自动完成了。

可变参数的原理:

  • 可变参数底层就是一个数组,根据传递参数个数不同,会创建不同长度的数组,来存储这些参数传递的参数个数,可以是0个(不传递),1,2...多个

参数的注意事项

  • 声明格式:方法名(参数的类型名 ...参数名)
  • 可变参数:方法参数部分指定类型的参数个数是可变多个:0个,1个或多个
  • 可变个数形参的方法与同名的方法之间,彼此构成重载
  • 可变参数方法的使用与方法参数部分使用数组是一致的
  • 方法的参数部分有可变形参,需要放在形参声明的最后
  • 在一个方法的形参位置,最多只能声明一个可变个数形参

举例:

package com.atguigu.java1;

/*
 * 可变个数形参的方法
 *
 * 1.jdk 5.0新增的内容
 * 2.具体使用:
 *   2.1 可变个数形参的格式:数据类型 ... 变量名
 *   2.2 当调用可变个数形参的方法时,传入的参数个数可以是:0个,1个,2个,。。。
 *   2.3 可变个数形参的方法与本类中方法名相同,形参不同的方法之间构成重载
 *   2.4 可变个数形参的方法与本类中方法名相同,形参类型也相同的数组之间不构成重载。换句话说,二者不能共存。
 *   2.5 可变个数形参在方法的形参中,必须声明在末尾
 * 	 2.6  可变个数形参在方法的形参中,最多只能声明一个可变形参。
 *
 */
public class MethodArgsTest {

    public static void main(String[] args) {

        MethodArgsTest test = new MethodArgsTest();
        //调用方法
        test.show("hello");
        test.show("hello", "world");
        test.show();

        test.show(new String[]{"AA", "BB", "CC"});

    }

    //定义含有可变参数的方法
    public void show(String... strs) {
        System.out.println("show(String ... strs)");

        for (int i = 0; i < strs.length; i++) {
            System.out.println(strs[i]);
        }
    }
    /*
    不能与上一个方法同时存在
      public void show(String[] strs){

     }
     */

}

可变参数的又一应用

package demo01;
 
public class ChangeArgs {
    public static void main(String[] args) {
        int[] arr = {1, 4, 62, 431, 2};
        int sum = getSum(arr);
        System.out.println(sum); // 500
        // 求 这几个元素和 6 7 2 12 2121
        int sum2 = getSum(6, 7, 2, 12, 2121);
        System.out.println(sum2);//2148
    }
 
    /**
     完成数组 所有元素的求和 原始写法
     public static int getSum(int[] arr){
       int sum = 0;
       for(int a : arr){
         sum += a; 
          }
           return sum; }
     */
    //可变参数写法
    public static int getSum(int... arr) {
        int sum = 0;
        for (int a : arr) {
            sum += a;
        }
        return sum;
    }
 
    //可变参数的特殊(终极)写法
    public static void method(Object... obj) {
    }

方法参数的值传递机制

方法,必须由其所在类或对象调用才有意义。若方法含有参数:

  • 形参:方法声明时的参数
  • 实参:方法调用时实际传给形参的参数值

​​​​​​​ 变量的赋值:

  •  如果变量是基本数据类型,此时赋值的是变量所保存的数据值。
  •  如果变量是引用数据类型,此时赋值的是变量所保存的数据的地址值。

值传递机制:

  • 如果参数是基本数据类型,此时实参赋给形参的是实参真实存储的数据值。
  • 如果参数是引用数据类型,此时实参赋给形参的是实参存储数据的地址值。

Java的实参值如何传入方法呢?

Java里方法的参数传递方式只有一种:值传递。 即将实际参数值的副本(复制品)传入方法内,而参数本身不受影响。

  • 形参是基本数据类型:将实参基本数据类型变量的“数据值”传递给形参
/*
 * 方法的形参的传递机制:值传递
 * 如果参数是基本数据类型,此时实参赋给形参的是实参真实存储的数据值。
 */
public class ValueTransferTest1 {
    public static void main(String[] args) {
 
        int m = 10;
        int n = 20;
 
        ValueTransferTest1 test = new ValueTransferTest1();
        test.swap(m, n);
        System.out.println("m = " + m + ", n = " + n);//m = 10, n = 20
 
    }
 
 
    public void swap(int m, int n) {
        //交换两个变量的值的操作
        int temp = m;
        m = n;
        n = temp;
        System.out.println("m = " + m + ", n = " + n);//m = 20, n = 10
    }
}
  • 形参是引用数据类型:将实参引用数据类型变量的“地址值”传递给形参
public class Person {
    int age;

    public static void main(String[] args) {
        Person obj = new Person();
        obj.age = 5;
        System.out.println("修改之前age = " + obj.age);// 修改之前age = 5
        // obj是实参
        change(obj);
        System.out.println("修改之后age = " + obj.age);// 修改之后age = 3
    }

    public static void change(Person obj) {
        System.out.println("change:修改之前age = " + obj.age);//change:修改之前age = 5
        obj.age = 3;
        System.out.println("change:修改之后age = " + obj.age);//change:修改之后age = 3
    }
}

需求

  • 定义一个Circle类,包含一个double型的radius属性代表圆的半径,一个 findArea()方法返回圆的面积。
  • 定义一个类PassObject,在类中定义一个方法printAreas(),该方法的定义 如下:public void printAreas(Circle c, int time) 在printAreas方法中打印输出1到time之间的每个整数半径值,以及对应的面积。 例如,time为5,则输出半径1,2,3,4,5,以及对应的圆面积。 在main方法中调用printAreas()方法,调用完毕后输出当前半径值。

定义Circle类

 
/*
 * 定义一个Circle类,包含一个double型的radius属性代表圆的半径,
 * 一个findArea()方法返回圆的面积。
 *
 */
 class Circle {
    double radius;//半径
 
    //求圆的面积
    public double findArea(){
        return Math.PI * radius * radius;
    }
}

定义PassObject类

 
public class PassObject {
 
    public static void main(String[] args) {
 
        Circle c = new Circle();
        printAreas(c, 5);
 
        System.out.println("now radius is " + c.radius);
    }
    
    public static void printAreas(Circle c, int time) {
 
        System.out.println("Radius\t\tArea");
        int i = 1;
        for (; i <= time; i++) {
            //设置圆的半径
            c.radius = i;
            double area = c.findArea();
            System.out.println(c.radius + "\t\t" + area);
        }
 
        c.radius = i;
    }
}

递归

递归概念:指在当前方法内调用自己的这种现象。方法递归包含了一种隐式的循环,它会重复执行某段代码,但这种重复执 行无须循环控制。 递归一定要向已知方向递归,否则这种递归就变成了无穷递归,类似于死循环。

递归的分类:

  • 递归分为两种,直接递归和间接递归。
  • 直接递归称为方法自身调用自己。
  • 间接递归可以A方法调用B方法,B方法调用C方法,C方法调用A方法。

注意事项:

  • 递归一定要有条件限定,保证递归能够停止下来,否则会发生栈内存溢出。
  • 在递归中虽然有限定条件,但是递归次数不能太多。否则也会发生栈内存溢出。
  • 构造方法,禁止递归

举例

package demo02;
 
public class Demo01Recurison {
    public static void main(String[] args) {
        //a();
        b(1);
    }
 
    /*
        构造方法,禁止递归
            编译报错:构造方法是创建对象使用的,一直递归会导致内存中有无数多个对象,直接编译报错
     */
    public Demo01Recurison() {
        //Demo01Recurison();
    }
 
    /*
            在递归中虽然有限定条件,但是递归次数不能太多。否则也会发生栈内存溢出。
                Exception in thread "main" java.lang.StackOverflowError
         */
    private static void b(int i) {
        System.out.println(i);
        if(i==20000){
            return; //结束方法
        }
        b(++i);
    }
 
    /*
        递归一定要有条件限定,保证递归能够停止下来,否则会发生栈内存溢出。
        Exception in thread "main" java.lang.StackOverflowError
     */
    private static void a() {
        System.out.println("a方法!");
        a();
    }
}

需求

计算1 ~ n的和

分析:num的累和 = num + (num-1)的累和,所以可以把累和的操作定义成一个方法,递归调用。

package demo02;
 
public class DiGuiDemo {
    public static void main(String[] args) {
        //计算1~num的和,使用递归完成
        int num = 5;
        // 调用求和的方法
        int sum = getSum(num);
        // 输出结果
        System.out.println(sum);//15
    }
 
    /*
    通过递归算法实现.
    参数列表:int
    返回值类型: int
    */
    public static int getSum(int num) {
        /* num为1时,方法返回1, 相当于是方法的出口,num总有是1的情况 */
        if (num == 1) {
            return 1;
        }
        /*
        num不为1时,
        方法返回 num +(num‐1)的累和
         递归调用getSum方法
         */
 
        return num + getSum(num - 1);
 
    }
}

代码执行图解 

                      

可。

在同一个类中,允许存在一个以上的同名方法,只要它们的参数个数或者参数
类型不同即可。
发布了20 篇原创文章 · 获赞 7 · 访问量 6620

猜你喜欢

转载自blog.csdn.net/weixin_44462792/article/details/105041031