前言
在编程中,往往会出现某段代码被频繁大量的调用的场景,如果每次都重新实现这段功能则会导致代码的复用性极低以及大大增加程序员所需要的维护量,不仅程序的开发效率低下,代码也会更为繁琐。所以作为一个合格的程序员,我们必须要学会如何正确使用方法以及如何实现方法的重载。
一、方法
1.1 方法的定义
方法简单来说就是一个代码片段,其意义类似于C 语言中的 “函数”。而方法存在的意义则是:
- 当代码规模较为复杂时,能够模块化的组织代码。
- 代码可复用。
- 部分场景下可以减少程序中的代码量,让代码更好被理解。
- 直接调用现有的方法进行开发,可以集中人力将频繁使用的底层方法写的更为精进,不必 考虑因各个程序员的水平不同而写出差异。
1.2 方法代码演示
1.2.1 检测一个年份是否为闰年(一)
//检测一个年份是否为闰年
import java.util.Scanner;
public class Test {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int year = scan.nextInt();
if(year % 100 == 0){
if(year % 400 == 0){
System.out.println(year + " is_leap_year");
}else {
if(year % 4 == 0){
System.out.println(year + " is_leap_year");
}
}
}else{
System.out.println(year + " is_not_leap_year");
}
scan.close();
}
}
结果如下
1.2.1 检测一个年份是否为闰年(二)
//使用方式检测一个年份是否为闰年
import java.util.Scanner;
public class Test {
public static boolean isLeapYear(int year) {
if ((year % 100 == 0 && year % 400 == 0) || (year % 100 != 0 && year % 4 == 0)) {
return true;
} else {
return false;
}
}
public static void main (String[]args){
Scanner scan = new Scanner(System.in);
int year = scan.nextInt();
boolean flag = isLeapYear(year);
System.out.println(flag);
scan.close();
}
}
结果如下
1.2.1 检测一个年份是否为闰年(三)
//使用方式检测一个年份是否为闰年
import java.util.Scanner;
public class Test {
public static void isLeapYear(int year){
if(year % 100 == 0){
if(year % 400 == 0){
System.out.println(year + " is_leap_year");
}else {
if(year % 4 == 0){
System.out.println(year + " is_leap_year");
}
}
}else{
System.out.println(year + " is_not_leap_year");
}
}
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int year = scan.nextInt();
isLeapYear(year);
scan.close();
}
}
结果如下
1.2.2 计算两个整数的和
import java.util.Scanner;
//使用方法计算两个整数的和
public class Test {
public static int sum(int num1,int num2){
return num1 +num2;
}
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
while (scan.hasNextInt()){
int num1 = scan.nextInt();
int num2 = scan.nextInt();
int ret = sum(num1,num2);
System.out.println(ret);
}
}
}
结果如下
1.2.3 计算 1-n的阶乘的和
//利用方法计算 1-n的阶乘的和
public class Test {
public static int fac(int n ){
int ret = 1;
for (int i = 1; i <= n; i++) {
ret *= i;
}
return ret;
}
public static int facSum(int n){
int sum = 0;
for (int i = 1; i <= n ; i++) {
sum += fac(5);
}
return sum;
}
public static void main(String[] args) {
System.out.println(fac(5));
System.out.println(facSum(6));
}
}
结果如下
1.2.4 交换两个变量中的数值
//交换两个变量中的数值
public class Test {
public static void main(String[] args) {
int a = 10;
int b = 20;
int tmp = a;
a = b;
b = tmp;
System.out.println(a + " " + b);
}
}
结果如下
1.2.4 交换两个变量中的数值(错误示范)
//交换两个变量中的数值
public class Test {
public static void swap(int a ,int b ){
int tmp = a;
a = b;
b = tmp;
}
//错误原因:实参与形参并不在同一块栈区空间,所以交换形参的值不会影响实参的值。
//在swap函数交换之后,形参x和y的值发生了改变,但是main方法中a和b还是交换之前的值,即没有交换成功
public static void main(String[] args) {
int a = 10;
int b = 20;
System.out.println("交换前:" + a + " " + b);
swap(a , b);//swap方法是没有返回值的,所以swap方法不需要接收返回值
System.out.println("交换前:" + a + " " + b);
}
}
//实参a和b是main方法中的两个变量,其空间在main方法的栈(一块特殊的内存空间)中,
//而形参x和y是swap方法中的两个变量,x和y的空间在swap方法运行时的栈中,因此实参a和b与形参x和y是两个没有任何关联性的变量
//在swap方法调用时,只是将实参a和b中的值拷贝了一份传递给了形参x和y,因此对形参x和y操作不会对实参a和b产生任何影响。
结果如下
2.3 方法调用的执行过程
调用方法—>传递参数—>找到方法地址—>执行被调方法的方法体—>被调方法结束返回—>回到主调方法继续往下
执行
2.4 实参和形参的关系
Java中方法的形参就相当于函数中的自变量,用来接收函数在调用时传递的值的。形参的名字可以随意取,对方法都没有任何影响,形参只是方法在定义时需要借助的一个变量,用来保存方法在调用时传递过来的值。
Java中,实参的值永远都是拷贝到形参中,形参和实参本质是两个实体。
2.5 学习小贴士
【注意事项】
- 修饰符:现阶段直接使用public static 固定搭配
- 返回值类型:如果方法有返回值,返回值类型必须要与返回的实体类型一致,如果没有返回值,必须写成void
- 方法名字:采用小驼峰命名
- 参数列表:如果方法没有参数,()中什么都不写,如果有参数,需指定参数类型,多个参数之间使用逗号隔开
- 方法体:方法内部要执行的语句
- 在java当中,方法必须写在类当中
- 在java当中,方法不能嵌套定义
- 在java当中,没有方法声明一说
2.6 方法重载
2.6.1 方法重载的含义
在Java中,如果多个方法的名字相同,参数列表不同,则称该几种方法被重载了。
2.6.2 方法签名
方法签名即:经过编译器编译修改过之后方法最终的名字。具体方式:方法全路径名+参数列表+返回值类型,构成
方法完整的名字。
public class Test {
public static int add(int x, int y) {
return x + y;
}
public static double add(double x, double y) {
return x + y;
}
public static void main(String[] args) {
int a = 10;
int b = 20;
System.out.println(add(a, b));
System.out.println("============");
double c = 22.5;
double d = 43.5;
System.out.println(add(c, d));
}
}
2.6.3 方法签名中的特殊符号说明
特殊字符 | 数据类型 |
---|---|
V | void |
Z | boolean |
B | byte |
C | char |
S | short |
I | int |
J | long |
F | float |
D | double |
[ | 数组(以[开头,配合其他的特殊字符,表述对应数据类型的数组,几个[表述几维数组) |
L | 引用类型,以L开头,以;结尾,中间是引用类型的全类名 |
2.6.4 方法重载代码示例
public class Test {
public static int addInt(int x, int y) {
return x + y;
}
public static double addDouble(double x, double y) {
return x + y;
}
public static void main(String[] args) {
int a = 10;
int b = 20;
System.out.println(addInt(a, b));
System.out.println("============");
double c = 22.5;
double d = 43.5;
System.out.println(addDouble(c, d));
}
}
结果如下
2.6.4 方法重载代码示例
public class Test {
public static int add(int x, int y) {
return x + y;
}
public static double add(double x, double y) {
return x + y;
}
public static void main(String[] args) {
int a = 10;
int b = 20;
System.out.println(add(a, b));
System.out.println("============");
double c = 22.5;
double d = 43.5;
System.out.println(add(c, d));
}
}
结果如下
2.6.5 学习小贴士
注意:
- 方法名必须相同
- 参数列表必须不同(参数的个数不同、参数的类型不同、类型的次序必须不同)
- 与返回值类型是否相同无关
- 两个方法如果仅仅只是因为返回值类型不同,是不能构成重载的
四、递归
4.1 递归的含义
- 一个方法在执行过程中调用自身, 就称为 “递归”。
- 递归有一个起始条件, 然后有一个递推公式。
4.2 递归的必要条件
- 将原问题划分成其子问题,注意:子问题必须要与原问题的解法相同
- 递归出口(有一个起始条件, 然后有一个递推公式.)
4.3 递归函数实例
4.3.1 求n的阶乘(递归)
//求n的阶乘(递归)
import java.util.Scanner;
public class Test {
public static int fucSum(int n ){
if(n == 1){
return 1;
}else {
return n * fucSum(n - 1);
}
}
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int n = scan.nextInt();
System.out.println(fucSum(n));
}
}
结果如下
4.3.2 用递归输出输入值的每一位
//用递归输出输入值的每一位
import java.util.Scanner;
public class Test {
public static void func(int n){
if(n < 10){
System.out.println(n);
return;
}else {
func(n / 10);
System.out.println(n % 10);
return;
}
}
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int n = scan.nextInt();
func(n);
}
}
结果如下
4.3.3 用递归求1-n的和
//利用递归求1-n的和
import java.util.Scanner;
public class Test {
public static int sum(int n ){
if(n == 1){
return 1;
}else {
return n + sum(n - 1);
}
}
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int n = scan.nextInt();
System.out.println(sum(n));
}
}
结果如下
4.3.4 计算输入值的每位相加的和
//计算输入值的每位相加的和
import java.util.Scanner;
public class Test {
public static int func(int n ){
if(n < 10){
return n;
}else {
int tmp = func(n / 10) + n % 10;
return tmp;
}
}
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int n = scan.nextInt();
System.out.println(func(n));
}
}
结果如下
4.3.5 求斐波那契数列
//递推公式求斐波那契数列
import java.util.Scanner;
public class Test {
public static int fib(int n ){
if(n == 1){
return 0;
}
if(n == 2){
return 1;
}
return fib(n - 2) + fib( n - 1);
}
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int n = scan.nextInt();
System.out.println(fib(n));
}
}
结果如下
4.3.5 求斐波那契数列
//递推公式求斐波那契数列
import java.util.Scanner;
public class Test {
public static int fib(int n ){
if(n == 1){
return 0;
}
if(n == 2){
return 1;
}
int f1 = 0;
int f2 = 1;
int f3 = -1;
for (int i = 3; i <= n ; i++) {
f3 = f1 + f2;
f1 = f2;
f2 = f3;
}
return f3;
}
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int n = scan.nextInt();
System.out.println(fib(n));
}
}
结果如下
五、总结
以上就是今天要讲的内容,java中的方法使用可以使代码的复用率提升并且更为简洁。