一、方法的基本语法
1、方法的定义
//方法定义
public static 方法返回值 方法名称(参数类型 形参){
方法体代码;
return 返回值;
}
//方法调用
返回值变量 = 方法名称(实参);
//实现两个整数相加
class Test{
public static void main(String[] args){
int a = 20;
int b = 10;
//方法的调用
int res = add(a,b);
System.out.println("ret=" + ret);
}
//方法的定义
public static int add(int x,int y){
return x + y;
}
}
//执行结果 ret = 30
注意:
- public 和 static 两个关键字在此处具有特定含义, 我们暂时不讨论, 后面会详细介绍
- 方法定义时, 参数可以没有. 每个参数要指定类型
- 方法定义时, 返回值也可以没有, 如果没有返回值, 则返回值类型应写成 void
- 方法定义时的参数称为 “形参”, 方法调用时的参数称为 “实参”
- 方法的定义必须在类之中, 代码书写在调用位置的上方或者下方均可
- Java中没有“函数声明”这样的概念
2、方法调用的执行过程
基本规则 - 定义方法的时候, 不会执行方法的代码,只有调用的时候才会执行
- 当方法被调用的时候,会将实参赋值给形参参数传递完毕后,就会执行到方法体代码
- 当方法执行完毕之后(遇到 return 语句),就执行完毕,回到方法调用位置继续往下执行
- 一个方法可以被多次调用
//计算1!+2!+3!+4!+5!
class Test{
public static void main(String[] args){
int sum = 0;
for(int i = 1; i <= 5; i++){
sum += factor(i);
}
System.out.println("sum=" + sum);
}
public static int factor(int n){
int result = 1;
for(int i = 1; i <= n; i++){
result *= i;
}
return result;
}
}
//执行结果 sum = 153
3、实参和形参的关系
class Test{
public static void main(String[] args){
int a = 10;
int b = 20;
swap(a,b);
System.out.println("a=" + a + "b=" + b);
}
public static void swap(int a, int b){
int tmp = a;
a = b;
b = tmp;
}
}
//运行结果 a = 10 b = 20
为什么没有完成交换?
对于基本数据类型来说,形参相当于实参的拷贝,即传值调用,没有改变实参的值
解决办法:传引用(例如数组)
class Test{
public static void main(String[] args){
int[] arr = {10,20};
swap(arr);
System.out.println("a=" + arr[0] + "b=" + arr[1]);
}
public static void swap(int[] arr){
int tmp = arr[0];
arr[0] = arr[1];
arr[1] = tmp;
}
}
//运行结果 a = 20 b = 10
二、方法的重载
1、重载的引入
有时候我们需要用同一个函数同时兼容多种参数的情况,就可以使用到方法的重载
class Test{
public static void main(String[] args){
int a = 10;
int b = 20;
int ret = add(a,b);
System.out.println("ret = " + ret);
double a2 = 10.5;
double b2 = 20.5;
double ret2 = add(a2,b2);
System.out.println("ret2 = " + ret2);
}
public static int add(int x, int y){
return x + y;
}
}
//编译出错
//错误:不兼容的类型:从double转换到int可能会有损失
由于参数类型不匹配导致错误,那么我们是不是应该这样写呢
class Test{
public static void main(String[] args){
int a = 10;
int b = 20;
int ret = add(a,b);
System.out.println("ret = " + ret);
double a2 = 10.5;
double b2 = 20.5;
double ret2 = add(a2,b2);
System.out.println("ret2 = " + ret2);
}
public static int addInt(int x, int y){
return x + y;
}
public static double addDouble(double x, double y){
return x + y;
}
}
//这样写也对,但是java认为addInt这种类型不友好,不如直接叫add
//使用重载:同一个方法名字,提供不同版本的实现
class Test{
public static void main(String[] args){
int a = 10;
int b = 20;
int ret = add(a,b);
System.out.println("ret = " + ret);
double a2 = 10.5;
double b2 = 20.5;
double ret2 = add(a2,b2);
System.out.println("ret2 = " + ret2);
}
public static int add(int x, int y){
return x + y;
}
public static double add(double x, double y){
return x + y;
}
}
2、重载的规则
针对同一个类
- 方法名相同
- 方法的参数不同(参数个数或参数类型)
- 方法的返回值类型不影响重载
- 当两个方法的名字相同,形参列表相同,但返回值不同的时候,不构成重载
三、方法的递归
1、递归的概念
一个方法在执行过程中调用自身,就称为递归
//递归求n的阶乘
class Test{
public static void main(String[] args){
int n = 5;
int ret = factor(n);
System.out.println("ret=" + ret);
}
public static int factor(int n){
if(n==1){
return 1;
}
return n * factor(n-1);
}
}
//执行结果 ret = 120
执行过程
2、小结
- 递归是一种重要的编程解决问题的方式
- 有的代码天然就是使用递归求解(例如斐波那契数、二叉树等),此时用递归比较容易
- 有的可以用递归和非递归解决,建议用非递归,可以提高高效性