方法
此笔记参考黑马教程,仅学习使用,如有侵权,联系必删
文章目录
1. 方法的定义
- 方法是一种语法结构,它可以把一段代码封装成一个功能,以便重复调用
1.1 方法的完整格式
修饰符 返回值类型 方法名(形参类型){
方法体代码(需要执行的功能代码)
return 返回值;
}
1.2 方法如何执行?
- 方法定义之后,必须调用才能跑起来,调用格式:
方法名(...);
int rs = sum(10, 20);
System.out.println(rs);
1.3 方法调用流程 - Debug
1.4 方法定义时几个注意点
- 方法的修饰符:暂时都使用
public static
修饰 - 方法申明了具体的返回值类型,内部必须使用 return 返回对应类型的数据
- 形参列表可以有多个,甚至可以没有;如果有多个形参,多个形参必须用 **, ** 隔开,且不能给初始化值
1.5 使用方法的好处是?
- 提高了代码的复用性,提高了开发效率
- 让程序的逻辑更清晰
代码演示
package h_define;
public class a_MethodDemo1 {
public static void main(String[] args) {
// 目标:掌握定义方法的完整格式,搞清楚使用方法的好处
// 需求:假如现在有很多程序员需要进行2个整数求和的操作
// 1. 李工
int rs = sum(10, 20);
System.out.println("和是:" + rs); // 30
// 2. 张工
int rs2 = sum(30, 20);
System.out.println("和是:" + rs2); // 50
}
public static int sum(int a, int b) {
int c = a + b;
return c;
}
}
总结
- 什么是方法?
- 方法是一种语法结构,它可以把一段代码封装成一个功能,以便重复使用
- 方法的完整格式是什么样的?
修饰符 返回值类型 方法名(形参类型){
方法体代码(需要执行的功能代码)
return 返回值;
}
- 方法要执行必须怎么办?
- 必须进行调用;调用格式:
方法名称(...);
- 使用方法有什么好处?
- 提高代码的复用性,提高开发效率,使程序逻辑更清晰
2. 方法的其他形式
- 方法定义时:需要按照方法解决的实际业务需求,来设计合理的方法形式解决问题
修饰符 返回值类型 方法名(形参列表){
方法体代码(需要执行的功能代码);
return 返回值;
}
- 方法是否需要接收数据处理?
- 方法是否需要返回数据?
注意事项:
- 如果方法不需要返回数据,返回值类型必须申明成 void(无返回值申明),此时方法内部不可以使用 return 返回数据
- 方法如果不需要接收数据,则不需要定义形参,且调用方法时也不可以传数据给方法了
- 没有参数且没有返回值类型(void)申明的方法,称为无参数、无返回值的方法,依次类推
代码实现
package h_define;
public class b_MethodDemo2 {
public static void main(String[] args) {
// 目标:掌握按照方法解决的实际业务需求不同,设计出合理的方法形式来解决问题
// 需求:打印多行行Hello World
printHelloWorld(3);
System.out.println("-------------------------------");
printHelloWorld(6);
}
/**
* 无参数,无返回值的方法
*/
public static void printHelloWorld(int n) {
for (int i = 1; i <= n; i++) {
System.out.println("Hello World");
}
}
}
总结
- 如果方法不需要接收数据处理,不需要返回数据,应该怎么办,要注意什么?
- 方法不需要接收数据,则形参列表可以不写;方法不需要返回数据,则申明返回值类型为 void
- 方法没有申明返回值类型(void),内部不能使用 return 返回数据
- 方法如果没有形参列表,调用的时候则不能传入参数,否则报错
3. 方法使用时的常见问题
- 方法在类中的位置放前后无所谓,但一个方法不能定义在另外一个方法里面
- 方法的返回值类型写 void(无返回申明)时,方法内不能使用 return 返回数据,如果方法的返回值类型写了具体类型,方法内部则必须使用 return 返回对应类型的数据
- return 语句的下面,不能编写代码,属于无效代码,执行不到这儿
- 方法不调用就不会执行,调用方法时,传给方法的数据,必须严格匹配方法的参数情况
- 调用有返回值的方法,有3种方式:1、可以定义变量接收结果 2、或者直接输出调用 3、甚至直接调用
- 调用无返回值的方法,只有1种方式:1、只能直接调用
代码实现
package h_define;
public class c_MethodProblemDemo3 {
public static void main(String[] args) {
// 目标:搞清楚使用方法时的几个常见问题
// 1. 方法在类中的位置放前后无所谓,但一个方法不能定义在另外一个方法里面
printHelloWorld();
// 2. 方法的返回值类型写void(无返回申明)时,方法内不能使用 return返回数据,如果方法的返回值类型写了具体类型,方法内部则必须使用 return 返回对应类型的数据
// 3. return 语句的下面,不能编写代码,属于无效代码,执行不到这儿
// 4. 方法不调用就不会执行,调用方法时,传给方法的数据,必须严格匹配方法的参数情况
printHelloWorld();
// int rs = sum(10, 20);
// System.out.println(rs); // 30
// 5. 调用有返回值的方法,有3种方式:1、可以定义变量接收结果 2、或者直接输出调用 3、甚至直接调用
int rs = sum(10, 20);
System.out.println(rs); // 30
// 直接输出调用
System.out.println(sum(10, 90)); // 100
// 直接调用
sum(100, 200);
// 6. 调用无返回值的方法,只有1种方式:1、只能直接调用
printHelloWorld();
}
public static void printHelloWorld() {
for (int i = 1; i <= 3; i++) {
System.out.println("Hello World");
}
}
public static int sum(int a, int b) {
int c = a + b;
return c;
// System.out.println("Hello World");
}
}
4. 方法的案例
4.1 设计方法的技巧,主要关注三方面:
- 方法是否需要接收数据进行处理?
- 要接收就要设计形参列表,不需要接收就不用设计形参列表?
- 方法是否需要返回数据?
- 如果方法需要返回数据就需要在方法的返回值类型这里为其声明数据的具体类型
- 方法要处理的业务(编程能力)
4.2 案例1
计算 1-n 的和
需求:
- 求 1-n 的和
分析:
- 方法是否需要接收数据进行处理?需要接收 n 的值,因此形参声明为:int n
- 方法是否需要返回数据?需要返回1-n的求和结果,因此返回值类型声明为 int
- 方法内部的业务:完成1-n的和并返回
代码实现
package h_define;
public class d_MethodTest4 {
public static void main(String[] args) {
// 目标:掌握设计方法的技巧
int rs = add(5);
System.out.println("1-5的和是:" + rs); // 15
int rs2 = add(100);
System.out.println("1-100的和是:" + rs); // 5050
}
public static int add(int n) {
int sum = 0;
for (int i = 1; i <= n; i++) {
// i = 1 2 3 ... n
sum += i;
}
return sum;
}
}
4.3 案例2
判断一个整数是奇数还是偶数
需求:
- 判断一个整数是奇数还是偶数,并把判断的结果输出出来
分析:
- 方法是否需要接收数据进行处理?需要接收一个整数来判断,因此形参声明为:int number
- 方法是否需要返回数据?方法内部判断完后直接输出结果即可,无需返回,因此返回值类型声明为:void
- 方法的内部业务:通过 if 语句判断 number 是奇数还是偶数,并输出结果
代码实现
package h_define;
public class e_MethodTest5 {
public static void main(String[] args) {
// 目标:掌握设计方法的技巧
judge(10); // 是一个偶数!
judge(7); // 是一个奇数!
}
public static void judge(int number) {
if (number % 2 == 0) {
System.out.println("是一个偶数!");
} else {
System.out.println("是一个奇数!");
}
}
}
总结
- 定义方法重点关注的是哪几点?
- 方法是否需要接收数据?也就是是否需要定义形参列表
- 方法是否需要返回数据?也就是是否需要声明具体的返回值类型
- 如何设计方法完成1-n的求和?
public static int sum(int n) {
int sum = 0;
for(int i = 1; i <= n; i++) {
sum += i;
}
return sum;
}
- 我们是如何设计方法来判断一个整数是奇数还是偶数的?
public static void judge(int number) {
if(number % 2 == 0) {
System.out.println(number + "这是一个偶数!");
System.out.println(number + "这是一个奇数!");
}
}
5. 方法在计算机中的执行原理
方法被调用的时候,是进入到栈内存中运行
栈:先进后出的一种容器
5.1 案例1
5.2 案例2
总结
- 方法的运行区域在哪里?
- 栈内存
- 栈有什么特点?方法为什么要在栈中运行自己?
- 先进后出
- 保证一个方法调用另一个方法,可以回来
6. Java 的参数传递机制
6.1 基本类型的参数传递
Java 的参数传递机制都是:值传递
- 所谓值传递:指的是在传输实参给方法的形参的时候,传输的是实参变量中存储的值的副本
- 实参:在方法内部定义的变量
- 形参:定义方法时“(…)”中所声明的参数
6.1.1 代码解释
package i_parameter;
public class a_MethodDemo1 {
public static void main(String[] args) {
// 目标:理解方法的参数传递机制:值传递
int a = 10;
change(a);
System.out.println("change3:" + a); // 10
}
public static void change(int a) {
System.out.println("change1:" + a); // 10
a = 20;
System.out.println("change2:" + a); // 20
}
}
总结
- Java 的参数传递机制是什么样的?
- 值传递,传输的是实参存储的值的副本
- 实参:在方法内部定义的变量
- 形参:以方法为例,就是方法定义时的变量
6.2 引用类型的参数传递
6.2.1 案例
package i_parameter;
public class b_MethodDemo2 {
public static void main(String[] args) {
// 目标:理解引用类型的参数传递机制:值传递的
int[] arrs = {10, 20, 30};
change(arrs);
System.out.println("main:" + arrs[1]); // 222
}
public static void change(int[] arrs) {
System.out.println("方法内1:" + arrs[1]); // 20
arrs[1] = 222;
System.out.println("方法内2:" + arrs[1]); // 222
}
}
- 原理图:
总结
- 基本类型和引用类型的参数在传递的时候有什么不同?
- 都是值传递
- 基本类型的参数传输存储的数据值
- 引用类型的参数传输存储的地址值
6.3 参数传递的案例
案例1
需求:
- 输出一个 int 类型的数组内容,要求输出格式为:[11, 22, 33, 44, 55]
分析:
- 方法是否需要接收数据进行处理?需要接收一个int 类型的数组,因此形参声明为:int[] arr
- 方法是否需要返回数据?方法内部直接输出数组内容即可,无需返回,因此返回值类型声明为:void
- 方法内部的业务:遍历数组,并输出相应的内容。
代码实现
package i_parameter;
public class c_MethodTest3 {
public static void main(String[] args) {
// 目标:完成打印int类型的数组内容
int[] arr = {10, 30, 50, 70};
printArray(arr); // [10, 30, 50, 70]
int[] arr2 = null;
printArray(arr2);
int[] arr3 = {};
printArray(arr3); // []
}
public static void printArray(int[] arr) {
if (arr == null) {
System.out.println(arr); // null
return; // 跳出当前方法
}
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.print(i == arr.length - 1 ? arr[i] : arr[i] + ", ");
}
System.out.println("]");
}
}
案例2
比较两个 int 类型的数组是否一样,返回 true 或者 false
需求:
- 如果两个 int 类型的数组,元素个数、元素顺序和内容是一样的我们就认为这2个数组是一摸一样的
例如:如下两个数组是一样的 int[] arrs = {10, 20, 30}; int[] arrs = {10, 20, 30};
分析:
- 方法是否需要接收数据进行处理?需要接收两个 int 类型的数组,因此,形参声明为:int[] arr1, int[] arr2
- 方法是否需要返回数据?方法判断完后需要返回:true、false,因此,返回值类型声明为 boolean 类型
- 方法内部的业务:判断两个数组内容是否一样。
代码实现
package i_parameter;
public class d_MethodTest4 {
public static void main(String[] args) {
// 目标:完成判断两个int类型的数组是否一样
int[] arr1 = null;
int[] arr2 = null;
System.out.println(equals(arr1, arr2)); // true
int[] arr3 = {10, 20, 30};
System.out.println(equals(arr1, arr3)); // false
int[] arr4 = {10, 20, 30, 40};
System.out.println(equals(arr3, arr4)); // false
int[] arr5 = {10, 21, 30};
System.out.println(equals(arr3, arr5)); // false
int[] arr6 = {10, 21, 30};
System.out.println(equals(arr5, arr6)); // true
}
public static boolean equals(int[] arr1, int[] arr2) {
// 1. 判断arr1和arr2是否都是null
if (arr1 == null && arr2 == null) {
return true; // 相等的
}
// 2. 判断arr1是null,或者arr2是null
if (arr1 == null || arr2 == null) {
return false; // 不相等
}
// 3. 判断2个数组的长度是否一样,如果长度不一样,直接返回false
if (arr1.length != arr2.length) {
return false; // 不相等
}
// 4. 两个数组的长度是一样的,接着比较它们的内容是否一样
for (int i = 0; i < arr1.length; i++) {
// 判断当前位置2个数组的元素是否不一样,不一样直接返回false
if (arr1[i] != arr2[i]) {
return false; // 不相等
}
}
return true; // 两个数组是一样的
}
}
7. 方法重载
7.1 定义
方法重载
- 一个类中, 出现多个方法的名称相同,但它们的形参列表是不同的,那么这些方法就称为方法重载了
7.2 注意事项
方法重载的注意事项
- 一个类中,只要一些方法的名称相同、形参列表不同,那么它们就是方法重载了,其它的都不管(如:修饰符、返回值类型是否一样都无所谓)
- 形参列表不同指的是:形参的个数、类型、顺序不同,不关心形参的名称
7.3 应用场景
方法重载的应用场景
- 开发中我们经常需要为处理一类业务,提供多种方案,此时用方法重载来设计是很专业的
代码演示
package j_overload;
public class a_MethodOverLoadDemo1 {
public static void main(String[] args) {
// 目标:认识方法重载,并掌握其应用场景
test(); // ===test1===
test(100); // ===test2===100
}
public static void test() {
System.out.println("===test1===");
}
public static void test(int a) {
System.out.println("===test2===" + a);
}
void test(double a) {
}
void test(double a, int b) {
}
void test(int b, double a) {
}
int test(int a, int b) {
return a + b;
}
}
案例
开发武器系统,功能要求如下:
- 可以默认发一枚武器
- 可以指定地区发射一枚武器
- 可以指定地区发射多枚武器
代码实现
package j_overload;
public class b_MethodTest2 {
public static void main(String[] args) {
// 目标:掌握方法重载的应用场景
fire(); // 发射了1枚武器给岛国
fire("米国"); // 发射了1枚武器给米国
fire("米国", 999); // 发射了999枚武器给米国
}
public static void fire() {
fire("岛国");
}
public static void fire(String country) {
fire(country, 1);
}
public static void fire(String country, int number) {
System.out.println("发射了" + number + "枚武器给" + country);
}
}
总结
- 什么是方法重载?
- 一个类中,多个方法的名称相同,但它们形参列表不同
- 方法重载需要注意什么?
- 一个类中,只要一些方法的名称相同、形参列表不同,那么它们就是方法重载了,其它的都不管(如:修饰符、返回值类型是否一样都无所谓)
- 形参列表不同指的是:形参的个数、类型、顺序不同,不关心形参的名称
- 方法重载有啥应用场景?
- 开发中我们经常需要为处理一类业务,提供多种解决方案,此时方法重载来设计是很专业的
补充知识:方法中独特使用 return 关键字
return 关键字在方法中单独使用
return;
可以在无返回值的方法中,作用是:立即跳出并结束当前方法的执行
代码演示
package k_returndemo;
public class a_ReturnDemo1 {
public static void main(String[] args) {
// 目标:掌握return单独使用:return; 在无返回值方法中的作用:跳出并立即结束当前方法的执行
System.out.println("程序开始。。。");
chu(10, 0);
System.out.println("程序结束。。。");
}
public static void chu(int a, int b) {
if (b == 0) {
System.out.println("您的数据有问题不能除0~~~");
return; // 跳出并结束当前方法的执行
}
int c = a / b;
System.out.println("除法结果是:" + c);
}
}
总结
- 在无返回值的方法中,如果要直接跳出并结束当前方法的执行,怎么解决?
return;
跳出并立即结束所在方法的执行break;
跳出并结束当前所在循环的执行continue;
结束当前所在循环的当次执行,进入下一次执行