方法的使用
Hello,各位。这个专栏,我会帮助大家通过简单易懂的方式学习,学懂,学精Java这门编程语言!欢迎大家与我积极探讨Java以及其他的知识。
✅wechat:Kepler-Antonia
✅QQ:162196770
✅gitee: https://gitee.com/jialebihaitao
✅文章专栏:https://blog.csdn.net/m0_53117341/category_11551619.html
1. 方法的概念及其使用
1.1 什么是方法?
1.1.1 方法的定义
方法,也叫函数,是完成特定功能的代码块。 简单来说,一个方法就是一个功能、一个动作或一种行为
1.1.2 为什么需要方法?
当一些代码被反复使用时,可以把它们提取出来,放到一个方法里,以方法的形式来使用这些代码。
1.1.3 方法的好处
大大提高了代码的复用性,方便维护
1.2 方法的格式
在初学阶段,我们这样理解就行.
1.2.1 方法的格式声明
- 修饰符:
public static
- 返回值类型:方法执行结果的数据类型
- 方法名:方法的名称,符合标识符命名规则即可
- 参数列表:方法执行需要的条件。
- 参数类型:可以是基本类型,也可以是引用类型;
- 参数名:即变量名
- 方法体语句:完成特定功能的代码
- return:意思是返回,用于结束方法。
- 返回值:方法执行之后的结果,返回给方法的使用者。若方法没有返回值,则它的返回值类型为void,比如main方法
在这里,举两个栗子~
-
栗子一:实现一个函数,判断一个年份是否是闰年
-
栗子2:实现一个两个整数相加的方法
1.2.2 注意事项
- 如果没有返回值,必须写成
void
- 方法名字:采用小驼峰命名
- 如果方法没有参数,( )中什么都不写.
- 方法必须写在类当中
- 方法不能嵌套定义
- 没有方法声明一说(与C语言对比)
1.2.3 形参与实参
形式参数:在定义方法时需明确方法参数的形式,比如参数的类型和个数,故方法定义时的参数列表称为形式参数
实际参数:调用方法时传递给方法的数据,必须符合形式参数的个数和对应位置的数据类型
1.3 方法调用过程图解
注意事项:
- 定义方法的时候, 不会执行方法的代码. 只有调用的时候才会执行.
- 一个方法可以被多次调用.
举两个栗子:
-
计算 n!
-
计算 1! + 2! + 3! + 4! + 5!
1.4 实参和形参的关系
在Java
中,本质上来说,都是按值传递,没有按址传递,形参是实参的一份临时拷贝
举个例子:交换两个整型变量
运行结果:
我们通过调试来看一下具体执行流程
可以看到,在swap函数交换之后,形参x和y的值发生了改变,但是main方法中a和b还是交换之前的值,即没有交换成功。而产生这样的原因
正是因为在Java
中,本质上来说,都是按值传递,没有按址传递,形参是实参的一份临时拷贝
1.5 没有返回值的方法
2. 函数重载
2.1 为什么需要方法重载?
当实现的功能相同,但具体的实现方式不同时,我们可以通过定义名称相同,参数(条件)不同的方法,来更好的识别和管理类中的方法。例如:
这样的话代码会特别乱,而且要记得方法名也很多,所以我们才会使用函数重载!
再举个栗子:
-
不使用函数重载
-
使用函数重载
代码明显可观许多
2.2 什么是方法重载?
在同一个类中的多个方法,它们的方法名相同,参数列表不同,这样的情况,称为方法重载。方法重载与修饰符和返回值类型无关。
-
方法名相同
-
参数列表不同(个数 顺序 类型)
-
数据类型不同:
-
个数不同:
-
顺序不同:
-
-
返回值没有要求[不影响重载]
所以真正需要考虑的是 方法名 和 参数列表
2.3 方法签名
方法签名即:经过编译器编译修改过之后方法最终的名字。具体方式:方法全路径名+参数列表+返回值类型,构成方法完整的名字。
先看这样一段代码:
我们先进行编译,然后使用JDK自带的javap反汇编工具查看,具体操作如下
- 找到代码所在地
- out文件夹->production文件夹
- 按住shift+右键,打开Powershell窗口
- 输入
javap -v TestMethod
(文件名)
3.递归
3.1 递归的概念
一个方法在执行过程中调用自身, 就称为 “递归”.
有些时候,我们遇到的问题直接并不好解决,但是发现将原问题拆分成其子问题之后,子问题与原问题有相同的解法,等子问题解决之后,原问题就迎刃而解了。这就是递归的思想
递归的必要条件:
- 将原问题划分成其子问题,注意:子问题必须要与原问题的解法相同
- 递归出口
3.2 递归的练习
3.2.1 递归求阶乘
public static int fac(int n) {
if(n == 1) {
return 1;
}
int tmp = n * fac(n-1);
return tmp;
}
3.2.2 按顺序打印一个数字的每一位
正序打印:
public static void func2(int n) {
if(n <= 9) {
System.out.println(n);
return;
}
func2(n/10);
System.out.println(n%10);//1 2 3
}
倒序打印:
public static void func2(int n) {
if(n <= 9) {
System.out.println(n);
return;
}
System.out.println(n%10);//3 2 1
func2(n/10);
}
3.2.3 递归求1+2+3+…+n
public static int sum(int n) {
if(n == 1) {
return 1;
}
int tmp = n+sum(n-1);
return tmp;
}
//传⼊n 1+2+3+4+…+n
//sum(n)=1+sum(9)
3.2.4 返回数字之和
写一个递归方法,输入一个非负整数,返回组成它的数字之和,例如,输入1729则应该返回1+7+2+9,它的和是19
public static int sumEvery(int n) {
if(n <= 9) {
return n;
}
int tmp = n%10+sumEvery(n/10);
return tmp;
}
//123->1+2+3->3+2+1->3+sumEvery(n/10)
3.2.5 递归求斐波那契数列(0、1、1、2、3、5、8、13、21、34、……)
public static int fib(int n) {
if(n == 1) {
return 0;
}
if(n == 2) {
return 1;
}
int tmp = fib(n-1)+fib(n-2);
return tmp;
}
另一种方法
public static int fib2(int n) {
if(n == 1) {
return 0;
}
if(n == 2) {
return 1;
}
int f1 = 0;
int f2 = 1;
int f3 = 0;
for (int i = 3; i <= n; i++) {
f3 = f1+f2;
f1 = f2;
f2 = f3;
}
return f3;
}
public static void main(String[] args) {
int[] array = {1,2,3};
print3(array,0);
/*System.out.println(fib2(1));
System.out.println(fib2(2));
System.out.println(fib2(3));
System.out.println(fib2(4));
System.out.println(fib2(42));*/
}
3.2.6 递归顺序打印数组的每个元素
public static void print(int[] array,int len) {
if(len == 1) {
System.out.println(array[len-1]);
return;
}
print(array,len-1);
System.out.println(array[len-1]);
}
逆序打印
public static void print2(int[] array,int len) {
if(len == 1) {
System.out.println(array[len-1]);
return;
}
System.out.println(array[len-1]);
print2(array,len-1);
}
public static void print3(int[] array,int len) {//前提:len传过来的是0
if(len == array.length-1) {
System.out.println(array[len]);
return;
}
print3(array,len+1);
System.out.println(array[len]);
}