一、方法的概念
**概念:**实现特定功能的一段代码,可反复使用。
二、方法的定义【重点】
2.1 方法的定义
定义语法:
经验:将需要在多个位置重复使用的一组代码,定义在方法内部。
2.2 定义的位置
方法定义在类的内部,与main方法并列。
正确位置:位置2、位置4
-
类的内部
-
方法和方法之间是平级关系 比如: printStr 和main
三、方法的调用
3.1 方法的调用
注意:调用方法时,会优先执行方法内部代码,结束后,返回到方法调用处,继续向下执行。
package com.qfedu.methoda;
public class Test02Method {
// main方法: 程序 的入口
// 修饰符 返回值 方法名(参数列表){
// 方法体
// }
//1 定义一个方法, 计算两个整数的和
//2. 这两个数,在 main中,控制台输入
//3. main方法中调用 计算两份个数的和的方法
public static void main(String[] args) {
add(2,2);
}
// 方法名(参数列表)
public static void add(int a,int b) {
System.out.println("a="+a);
System.out.println("b="+b);
int sum = a+b;
System.out.println("这两个数的和是:"+sum );
}
}
四、方法的参数【重点】
4.1 方法的参数
多数情况下,方法与调用者之间需要数据的交互;调用者必须提供必要的数据,才能使方法完成相应的功能。
调用方法时,所传入的数据被称为 “参数” 。
4.2 形参与实参
方法名称和形参名要符名 标识符的定义
定义语法:
public static void 方法名称( 形式参数 ){
//方法主体
}
经验: “形参”等价于“局部变量的声明”。
调用语法:
方法名称( 实际参数 );
经验:“实参”等价于“局部变量的赋值”。
作用:
方法的参数可以让代码功能更灵活、普适性更高,易于修改及维护。
4.2.1 单个参数
public static void 方法名(参数的类型 参数名) {
方法体;
}
参数名: 形参
4.2.2 多个参数
public static void 方法名(参数的类型 参数名, 参数的类型 参数名,参数的类型 参数名,参数的类型 参数名,参数的类型 参数名.....) {
方法体;
}
练习1:调用方法输出字符串
package com.qfedu.methoda;
public class Test03 {
//1 定义一个方法, 计算两个整数的和
//2. 这两个数,在 main中,控制台输入
//3. main方法中调用 计算两份个数的和的方法
public static void main(String[] args) {
//say("我胡汉三又回来了,你们走着瞧");
String aa ="I love you ";
say(aa);
String bb = "I love myself";
say(bb);
}
// 我说一句话, 这个方法的功能是 打印10 次这句话
// say(参数的类型 参数的名称,类型 名称,类型 名称.......)
// say(形参)
public static void say(String str) {
for(int i=0; i<10; i++) {
System.out.println(str);
}
}
}
练习2:计算两个数的 + - * / %
package com.qfedu.methoda;
import java.util.Scanner;
public class Test04Method {
// 写 以下方法
// 计算两个数的 + - * / %
//注意: 参数类型必须匹配; 参数个数必须匹配
public static void main(String[] args) {
//1 .定义扫描器
Scanner sc = new Scanner(System.in);
// 2. 输入两个int 类型的值 a ,b
System.out.println("请输入两个数:");
int a = sc.nextInt();
int b = sc.nextInt();
// 3. 输入你要做的计算符号 + - * / %
System.out.println("请输入计算符号:");
String type = sc.next();
// 4. 判断 计算符号, 依据计算符号选择 调用的方法
if(type.equals("+")) {
add(a,b);
}else if(type.equals("-")) {
sub(a,b);
}else if(type.equals("*")) {
multi(a,b);
}else if(type.equals("/")) {
chu(a,b);
}else if(type.equals("%")) {
mod(a,b);
}else {
System.out.println("计算符号不合法.....");
}
}
// +
public static void add(int a,int b) {
int sum = a+b;
System.out.println("a+b="+ sum );
}
// -
public static void sub(int a,int b) {
int sum = a-b;
System.out.println("a-b="+sum);
}
// /
public static void chu(int a,int b) {
int sum = a/b;
System.out.println("a/b="+sum);
}
// *
public static void multi(int a,int b) {
int sum = a*b;
System.out.println("a*b="+sum);
}
// %
public static void mod(int a,int b) {
int sum = a%b;
System.out.println("a%b="+sum );
}
}
练习3:优化练习2
package com.qfedu.methoda;
public class Test03Method {
// 写 以下方法
// 计算两个数的 + - * / %
//注意: 参数类型必须匹配; 参数个数必须匹配
public static void main(String[] args) {
int a = 101;
int b = 345;
// +
add(a,b);
// -
sub(a,b);
multi(a,b);
chu(a,b);
mod(a,b);
}
// +
public static void add(int a,int b) {
int sum = a+b;
System.out.println("a+b="+ sum );
}
// -
public static void sub(int a,int b) {
int sum = a-b;
System.out.println("a-b="+sum);
}
// /
public static void chu(int a,int b) {
int sum = a/b;
System.out.println("a/b="+sum);
}
// *
public static void multi(int a,int b) {
int sum = a*b;
System.out.println("a*b="+sum);
}
// %
public static void mod(int a,int b) {
int sum = a%b;
System.out.println("a%b="+sum );
}
}
4.3 如何定义参数
经验:根据具体的业务需求,来定义方法的参数。
案例: 用户登录
public class TestUser {
public static void main(String[] args) {
//1.从前端获取的username password
String userName ="zs";
String passWord = "123";
//2. 登录
login(userName,passWord);
//调用修改密码操作
changePass("123","123","456","456");
}
//用户登录的方法
//输入用户名和密码
public static void login(String userName, String passWord) {
// zs 123
if(userName.equals("zs") && passWord.equals("123")) {
System.out.println("登录成功!");
}else {
System.out.println("登录失败");
}
}
//手机号和验证码
public static void login1(String phone,int code) {
if(phone.equals("123") && code==123) {
System.out.println("登录成功");
}else {
System.out.println("登录失败");
}
}
//用户修改密码的方法
//需求: 输入手机号 验证码 新密码 再次新密码
/**
*
* @param phone 手机号
* @param code 验证码
* @param newPass1 新密码
* @param newPass2 再次新密码
*/
public static void changePass(String phone,String code,String newPass1,String newPass2) {
//1.手机号和验证码通过,则继续
if(phone.equals("123456") && code.equals("123")) {
//2. 判断两次新密码
if(newPass1.equals(newPass2)) {
System.out.println("操作数据库,更新成功");
}else {
System.out.println("两次密码不一致,请重新输入");
}
}else {
System.out.println("手机号和验证码不一致");
}
}
}
五、返回值与返回值类型
5.1 返回值
概念: 方法执行后的返回结果。
方法执行后,一些情况下无需返回结果;另一些情况下则必须返回结果。
例如:
存款操作无需返回结果。
取款操作必须返回结果。
5.2 定义语法
public static 返回值类型 方法名称( 形式参数列表 ){
//方法主体
return value; //返回值
}
规定返回值的具体类型(基本、引用、void)。
根据需求返回一个结果(值)。
5.3 调用语法
变量 = 方法名称( );
变量类型与返回值类型一致。
5.4 需求
需求:定义方法,计算两个整数的和,并返回结果,在main中打印。
public class TestSum {
//计算任意两个数的和,要求键盘输入 用方法来写逻辑代码 , 并且 在main方法中调用,把结果打印在main方法中
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int a = sc.nextInt();
int b = sc.nextInt();
int sum = sum(a,b);
System.out.println("a+b="+sum);
}
//void 表示没有返回结果: null
// 1. void --> int
//2. 在方法的代码当中,要有对应类型就量的返回
public static int sum(int a ,int b ) {
int sum = a+b;
System.out.println(sum);
//返回结果:要求类型与 方法定义的类型相同,return 返回结果,表示方法结束
return sum ;
}
}
5.5 return关键字
return的两种用法:
应用在具有返回值类型的方法中:
return value; 表示结束当前方法,并伴有返回值,返回到方法调用处。
应用在没有返回值类型(void)的方法中:
return; 表示结束当前方法,直接返回到方法调用处。
注意:一个类中可以定义多个方法,方法之间属于并列关系,不可嵌套。
经验:一个方法只做一件事。
案例 :计算1-10的和
package com.qfedu;
public class Test01 {
// 1. 写一个方法, 计算 1-10 的和
// 2. 在main中调用
// 3. 在main 方法中,计算 平均数
public static void main(String[] args) {
// 方法的返回值
// void 表示本方法,没有返回值
// 如果有返回值,把void 换成 对应的返回类型
// 如果有返回值 在方法中要添加 return 返回值
// 如果有返回值 , 返回值的类型必须和 return 后边值的类型一致
// 如果有返回值,调用方法的结果,要用对应的类型去接
// 调用
int a = sum();
System.out.println("平均数="+(a/10));
String str = say();
System.out.println("我想说的一句话是:"+str);
}
/**
* 计算1-10 的和
*/
public static int sum() {
int sum = 0;
for(int i=0; i<=10; i++) {
sum += i;
}
return sum ;
}
public static String say() {
String str = "昨晚没有睡好,你猜为什么?";
return str;
}
}
案例 :+ - * / % 计算
package com.qfedu;
import java.util.Scanner;
/**
* @Author lcw
* @Description
* @Date 2021/11/5
*/
public class Test02 {
// 1. 写一个方法, 计算 1-10 的和
// 2. 在main中调用
// 3. 在main 方法中,计算 平均数
public static void main(String[] args) {
// 方法的返回值
// void 表示本方法,没有返回值
// 如果有返回值,把void 换成 对应的返回类型
// 如果有返回值 在方法中要添加 return 返回值
// 如果有返回值 , 返回值的类型必须和 return 后边值的类型一致
// 如果有返回值,调用方法的结果,要用对应的类型去接
//1.定义扫描器
Scanner sc = new Scanner(System.in);
while (true) {
System.out.println("--------------------开始计算--------------------");
System.out.print("请输入第一个数:");
int num1 = sc.nextInt();
System.out.print("请输入第二个数:");
int num2 = sc.nextInt();
System.out.print("请输入计算符号:");
String flag = sc.next();
//2.调用方法
int result = count(num1,num2,flag);
System.out.println("计算结果:"+num1+flag+num2+"="+ result);
}
}
//1. 写一个计算器,参数是 数字a ,b 计算符号
// 2. 返回结果是一个int
public static int count(int a,int b,String fh) {
// result 这个单词是结果的意思
int result =0;
// fh + - * / %
if(fh.equals("+")) {
result = a+b;
}else if(fh.equals("-")) {
result = a-b;
}else if(fh.equals("*")) {
result = a*b;
}else if(fh.equals("/")) {
result = a/b;
}else if(fh.equals("%")) {
result = a%b;
}else {
result = -1;
}
return result;
}
}
六、方法的好处
好处:
减少代码冗余。
提高复用性。
提高可读性。
提高可维护性。
方便分工合作。
七、递归
注意事项
1.递归的使用注意事项,并举例应用场景方法不停地进栈而不出栈,导致栈内存不足
2.如果使用循环可以解决,则优先使用循环
3.一定要有结束条件
场景: 可以用来操作文件目录:比如文件统计总大小,删除目录及基目录下的所有文件
生活举例:
简单的从字面意思来,就是既有传递又有回归的算法,就叫做递归。比如:你在电影院看电影,凑巧的是你来迟了,一懵,发现自己的座位号找不到,你就开始问旁边的人,你是第几号,然后旁边的人又不知道,又问旁边的人,那个人又不知道,之后他又问旁边的人,依次类推,等到你问到最前面的时候,那个人知道自己的座位号,就告诉他旁边的人,然后他们一个又一个的把消息传递回来,直到你知道自己的作为在哪里。这就是所谓的递归;
7.1 多级调用
运行结果:
m1() - start
m2() - start
m2() - end
m1() - end
优先执行方法内部代码,结束后,返回到调用处,继续向下执行。
7.2 无穷递归
运行结果:
m1() - start
m1() - start
m1() - start
m1() - start
m1() - start
m1() - start
m1() - start
m1() - start
m1() - start
m1() - start
7.3 递归
什么是递归?
解决具有既定规律的问题时,在方法内部再次调用自身方法的一种编程方式。
何时使用递归?
当需要解决的问题可以拆分成若干个小问题,大小问题的解决方式相同,方法中自己调用自己。
使用循环解决的常规问题,都可以替换为递归解决。
如何正确使用递归?
设置有效的出口条件,可以让调用链上的每个方法都可以正确返回,避免无穷递归。
7.4 循环阶乘
计算5的阶乘:5!= 5 * 4 * 3 * 2 * 1;
循环计算阶乘较为简单,依次与每个值相乘即可。
7.5 递归阶乘
阶乘的定义:n ! = n * (n-1) * (n-2) * (n-3) . . . .
多个方法解决问题的思路相同,同时遵循着相同的规律。
注意:所有能以递归解决的问题,循环都可以解决。当解决复杂问题时,递归的实现方式更为简单。
public class Test7factorial {
// 5! = 5* 4 *3 * 2*1
//5! = 5* 4!
// 4!= 4*3!
// 3! = 3*2!
// 2! = 2*1!
// 1* =1*1;
public static void main(String[] args) {
int factorial = factorial(5);
System.out.println(factorial);
}
//求阶乘的方法
public static int factorial(int n) {
if(n==1) {
return 1;
}
return n*factorial(n-1);
// 5 * (factorial(4))
// 5* 4* factorial(3)
// 5* 4* 3* factorial(2)
// 5* 4* 3* 2* factorial(1)
// 5* 4* 3* 2* 1
}
}
案例: 1-100的和
package com.qfedu;
public class Test08 {
//1-100的和
public static void main(String[] args) {
int add = add(100);
System.out.println(add);
}
// 100+(1-99)
// 100 + 99 + (1-98)
// 100 + 99 + 98 + (1-97)
public static int add(int n ) {
if(n==1) {
return 1;
}
return n+ add(n-1);
}
}