八、方法

110 阅读8分钟

一、什么是方法?

1. 什么是方法?

  • 方法(method)是程序中最小的执行单元

2. 实际开发中方法的应用场景

  • 提高代码的复用性
  • 提高代码可维护性

总结

    1. 什么是方法?
    • 方法是程序中最小的执行单元
    1. 实际开发中,什么时候用到方法?
    • 重复的代码,具有独立功能的代码可以抽取到方法中
    1. 实际开发中,方法有什么好处?
    • 可以提高代码的复用性
    • 可以提高代码的可维护性

二、方法的格式?

1. 方法的格式

把一些代码打包在一起,用到的时候就调用

  • 方法定义
    • 把一些代码打包在一起,该过程成为方法定义
  • 方法调用
    • 方法定义后并不是直接运行的,需要手动调用才能执行,该过程称为方法调用

2. 方法的定义格式

public static 返回值类型 方法名(参数) {
    方法体;
    return 返回值;
}

3. 最简单的方法定义和调用

定义
// 格式
public static void 方法名() {
    方法体(就是打包起来的代码);
}

// 例子
public static void play() {
    System.out.println("玩");
}
调用
// 格式
方法名();

// 例子
play();

注意:方法必须先定义后调用,否则程序将报错

练习:人肉计算器

需求:定义一个方法,在方法内部定义两个变量。求出它们的和并进行打印

public class MethodTest1 {  
    public static void main(String[] args) {  
        getSum();  
    }  
    public static void getSum() {  
        int num1 = 10, num2 = 20, sum = 0;  
        sum = num1 + num2;  
        System.out.println(sum);  
    }  
}

4. 带参数的方法定义和调用

定义
// 格式
public static void 方法名(参数1, 参数2, 参数3...) {...}

// 例子
public static void play(int number1, int number2, int number3...) {...}
调用
// 格式
方法名(参数1, 参数2, 参数3...);

// 例子
play(10,20,30...);

注意:方法调用时,参数的数量与类型必须与方法定义中小括号里面的变量一一对应,否则程序将报错

public class MethodTest2 {  
    public static void main(String[] args) {  
        getSum(1, 2);  
    }  
    public static void getSum(int num1, int num2) {  
        int res = num1 + num2;  
        System.out.println(res);  
    }  
}
形参和实参
  • 形参:全称形式参数,是指方法定义中的参数
  • 实参:全称实际参数,方法调用中的参数

注意:方法调用时,形参和实参必须一一对应,否则程序将报错

练习

需求:定义一个方法,求长方形的周长,将结果在方法中进行打印

public class MethodTest4 {  
    public static void main(String[] args) {  
        getArea(5.2,7);  
    }  
    public static void getArea(double width, double len) {  
        System.out.println(width * len);  
    }  
}

练习

需求:定义一个方法,求圆的面积,将结果在方法中进行打印

public class MethodTest5 {  
    public static void main(String[] args) {  
        getAres(7);  
    }  
    public static void getAres(double num) {  
        System.out.println(3.14159265357 * num * num);  
    }  
}

5. 带返回值方法的定义和调用

方法的返回值其实就是方法运行的最终结果

  • 如果在调用处要根据方法的结果,去编写另外一段代码逻辑
  • 为了在调用处拿到方法产生的结果,就需要定义带有返回值的方法
定义
// 格式
public static void 方法名(参数1, 参数2) {
    方法体;
    return 返回值;
}

// 例子
public static int play(int num1, int num2) {
    int res = num2 + num2;
    return res;
}
调用
  • 直接调用
    • 方法名(实参);
  • 赋值调用
    • 整数类型 变量名 = 方法名(实参);
  • 输出调用
    • System.out.println(方法名(实参));

总结

    1. 什么时候用到有返回值的方法?
    • 在调用处要根据方法的结果,去编写另外一段代码
    1. 有返回值方法的定义格式
public static 返回值类型 方法名 (参数) {
    方法体了:
    return 返回值;
}
    1. 有返回值方法的调用格式
    • 直接调用,赋值调用,输出调用
    1. 有返回值方法中参数的运行过程

练习

需求:定义方法,比较两个长方形的面积

public class MethodTest3 {  
    public static void main (String[] args) {  
        double area1 = getArea(5.3, 2.7);  
        double area2 = getArea(7.3, 1.7);  
        if (area1 > area2) {  
            System.out.println("第一个长方形面积大");  
        } else {  
            System.out.println("第二个长方形面积大");  

        }  
    }  
    public static double getArea(double width, double len) {  
        return width * len;  
    }  
}

6. 方法的完整定义格式

public static 返回值类型 方法名(参数) {
    方法体;
    return 返回值;
}

7. 方法的注意事项

  • 方法不调用就不执行
  • 方法与方法之间是平级关系,不能相互嵌套定义
  • 方法的编写顺序和执行顺序无关
  • 放阿飞的返回值类型为 void,表示该方法没有返回值,没有返回值的方法可以省略 return 语句不写,如果非要编写 return,后面不能跟具体的数据
  • return 语句下面,不能编写代码,因为永远执行不到,属于无效的代码

8. return 关键字

  • 方法没有返回值:可以省略不写。如果书写,表示结束方法
  • 方法有返回值:必须要写。表示结束方法和返回结果

三、方法的重载?

1. 方法的重载

  • 在同一个类中,定义了多个同名的方法,这些同名的方法具有同种功能
  • 每个方法具有不同的参数类型或参数个数,这些同名的方法,就构成了重载关系
  • 同一个类中,方法名相同,参数不同的方法。与返回值无关。
    • 参数不同:个数不同、类型不同、顺序不同

java 虚拟机会通过参数的不同来区分同名的方法

练习:方法重载

需求:使用方法重载的思想,设计比较两个整数是否相同的方法

要求:兼容全整数类型(byte、short、int、long)

public class MethodTest6 {  
    public static void main(String[] args) {  
        byte num1 = 1;  
        byte num2 = 2;  
        compare(num1, num2);  
    }  
    public static void compare(int i1, int i2) {  
        System.out.println("int");  
        System.out.println(i1 == i2);  
    }  
    public static void compare(byte b1, byte b2) {  
        System.out.println("byte");  
        System.out.println(b1 == b2);  
    }  
    public static void compare(short s1, short s2) {  
        System.out.println("short");  
        System.out.println(s1 == s2);  
    }  
    public static void compare(long l1, long l2) {  
        System.out.println("long");  
        System.out.println(l1 == l2);  
    }  
}

练习:数组遍历

需求:设计一个方法用于数组遍历,要求遍历的结果是在同一行上。如:[11,22,33,44,55]

public class MethodTest7 {  
    public static void main(String[] args) {  
        int[] arr = {11,22,33,44,55};  
        forArr(arr);  
    }  
    public static void forArr(int[] arr) {  
        System.out.print("[");  
        for (int i = 0; i < arr.length; i++) {  
            if (i == arr.length - 1) {  
                System.out.print(arr[i] + "]");  
            } else {  
                System.out.print(arr[i] + ", ");  
            }  
        }  
    }  
}
  • 关于打印
    • System.out.println("123"); // 先打印123,再进行换行
    • System.out.print("123"); // 只打印123,不换行
    • System.out.println(); // 不打印任何数据,只做换行处理

练习:数组最大值

需求:设计一个方法求数组的最大值,并将最大值返回

public class MethodTest8 {  
    public static void main(String[] args) {  
        int[] arr = {1,5,7,3,8,10,8};  
        int max = getMax(arr);  
        System.out.println(max);  
    }  
    public static int getMax(int[] arr) {  
        int max = arr[0];  
        for (int i = 1; i < arr.length; i++) {  
            if (max < arr[i]) {  
                max = arr[i];  
            }  
        }  
        return max;  
    }  
}

练习:判断是否存在

需求:定义一个方法判断数组中的某一个数是否存在,将结果返回给调用处

public class MethodTest9 {  
    public static void main(String[] args) {  
        int[] arr = {1,4,9,3,5,7,9};  
        boolean flag = contain(arr, 6);  
        System.out.println(flag);  
    }  
    public static boolean contain(int[] arr, int num) {  
        for (int i = 0; i < arr.length; i++) {  
            if (arr[i] == num) {  
                return true;  
            }  
        }  
        return false;  
    }  
}
  • return break 关键字的区别
    • return关键字
      • 其实跟循环没有什么关系,跟方法有关的,表示1结束方法 2返回结果;如果方法执行到了return,那么整个方法全部结束,里面的循环也会随之结束
    • break关键字
      • 跟方法无关,结束循环或者switch的

练习:复制数组

需求:定义一个方法 copyOfRange(int[], int from, int to)

功能:将数组arr中从索引from(包含from)开始。到索引to结束(不包含to)的元素复制到新数组中,将新数组返回。

public class MethodTest10 {  
    public static void main(String[] args) {  
        int[] arr = {3,6,3,7,2,9,8,0,1};  
        int[] newArr = copyOfRange(arr, 3, 7);  
        for (int i = 0; i < newArr.length; i++) {  
            System.out.print(newArr[i] + " ");  
        }  
    }  
    public static int[] copyOfRange(int[] arr, int from, int to) {  
        int[] newArr = new int[to - from];  
        for (int i = from; i < to; i++) {  
            newArr[i - from] = arr[i];  
        }  
        return newArr;  
    }  
}

四、方法的内存

1. 方法调用的基本内存原理

栈:先进后出

  • main方法先入栈
  • 执行main方法内部代码
  • 遇到方法调用就将调用的该方法压入栈中
  • 执行调用的方法内部的代码
  • 执行完毕后,调用的方法出栈
  • 接着执行调用方法之后的代码
  • main方法内部代码执行完毕,出栈

2. 基本数据类型和引用数据类型

  • 基本数据类型:数据值是存储在自己空间中
    • 特点:赋值给其它变量,也是赋的真实值
  • 引用数据类型:数据值是存储在其他空间中,自己空间中存储的是地址值
    • 特点:赋值给其他变量,赋的是地址值

3. 方法传递基本数据类型的内存原理

传递基本数据类型时,传递的是真实的数据,形参的改变,不影响实际参数的值

4. 方法传递引用数据类型的内存原理

传递引用数据类型时,传递的是地址值,形参的改变,影响实际参数的值

5. 方法传递参数的结论

  • 基本数据类型
    • 传递的是真实的数据
  • 引用数据类型
    • 传递的是地址值