概述
一.方法的基本用法
1.1.什么是方法
1.方法就是一个代码片段,类似于C语言中的“函数”。
2.方法的定义:可以使代码段重复使用。(复用)
3.方法存在的意义:
*能够模块化的组织代码(当代码规模比较复杂的时候)
*做到代码被重复使用,一份代码可以在多个位置使用。
*让代码更好理解更简单
*直接调用现有方法开发,不必重复造轮子
1.2.方法定义语义
1.基本语法:
// 方法定义
public static 方法返回值 方法名称([参数类型 形参 ...]){
方法体代码;
[return 返回值];
}
// 方法调用
返回值变量 = 方法名称(实参...);
例:定义一个方法实现两个整数相加
public class Class1 {
public static void main(String[] args) {
int a=10;
int b=20;
//方法的调用
int ret=add(a,b);
System.out.println("ret="+ret);
}
//方法的定义
public static int add(int x, int y) {
return x + y;
}
}
//执行结果 ret=30
2.注意事项:
*public和static两个关键字具有特定含义,暂不讨论,后面会详细介绍。
*方法定义时,参数可以没有,每个参数要指定类型。
*方法定义时,返回值也可以没有,如果没有返回值,则返回值类型应该写成void。
*方法定义时的参数称为“形参”,方法调用时的参数称为“实参”。
*方法的定义必须在类之中,调用方法的位置在方法定义之前之后都可以。
*在java中,没有方法声明概念。(定义一个方法,必须有方法体实现{})
1.3方法调用的执行过程
1.基本规则:
*定义方法的时候,不会执行方法的代码,指有调用的时候才会执行。
*当方法被调用的时候,会将实参赋值给形参。
*参数传递完毕后,就会执行到方法体代码。
*当1方法执行完毕之后(遇到return语句),就执行完毕,回到方法调用位置继续往下执行。
*一个方法可以被多次调用。
例:计算1!+2!+3!+4!+5!
public class Class1 {
public static void main(String[] args) {
int sum=0;
//1!+2!+3!+4!+5!
for(int i=1;i<=5;i++){
int temp=0;
//当前i的阶乘值
temp=factor(i);
sum+=temp;
}
System.out.println(sum);
}
/**
* 此方法用来计算传入值n的阶乘
* @param n 要计算的阶乘数
* @return n的阶乘值
*/
public static int factor(int n){
int ret=1;
for(int i=1;i<=n;i++){
ret*=i;
}
return ret;
}
}
//执行结果: 153
1.4方法的返回值
一个方法可以有返回值也可以没有返回值。根据当前这个方法的作用来判断。
当没有返回值,我们使用void来声明方法。
当在没有返回值的方法中使用return;表示当前方法结束调用,后面的代码不再执行。
public class test {
public static void main(String[] args) {
int num=6;
fun(num);
}
public static void fun(int num) {
if(num%3==0){
System.out.println("num是三的倍数");
return;
}
System.out.println("hehe");
}
}
//写了return; 则执行结果为 num是三的倍数
//没写return; 则执行结果为 num是三的倍数 hehe
1.5实参和形参的关系
Java中的参数传递只有值传递
例:交换两个整型变量
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 x, int y) {
int tmp = x;
x = y;
y = 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.方法重载(overload)与方法重写(也叫方法覆写override)不同。当我们需要用一个函数同时兼容多种参数的情况,就可以使用到方法重载。
2.方法重载(别看返回值):发生在同一个类中的不同方法。
3.方法重载表示一组方法的方法名称完全相同,参数的个数或类型不同,与方法返回值无关!!!方法的返回值类型不影响重载。
例:
public class test {
public static void main(String[] args) {
int a=6;
int b=20;
int sum=add(a,b);
System.out.println(sum);
int a1=9;
int b1=1;
int c1=12;
int sum1=add(a1,b1,c1);
System.out.println(sum1);
double a2=1;
double b2=2;
double c2=12;
double sum2=add(a2,b2,c2);
System.out.println(sum2);
}
private static int add(int a, int b) {
return a+b;
}
//重载方法
private static int add(int a1, int b1, int c1) {
return a1+b1+c1;
}
//重载方法
private static double add(double a2, double b2, double c2) {
return a2+b2+c2;
}
}
4.当两个方法的名字相同,参数也相同,但返回值不同的时候,不构成方法重载。
(下面代码中两个方法的名字相同,参数也相同,但返回值类型分别为int和double,编译报错)
5.println之所以所有参数都能传,原因就是定义了一些列的重载方法。
三、方法递归
方法递归:程序结构,在数据结构与算法部分是基础
数据结构:数据如何存储就是数据结构
算法:数据如何处理就叫算法
1.1递归的概念
一个方法在执行的过程中调用自身,就称为“递归”。(一定注意方法递归的语义!!即这个方法能干嘛,不用去想程序内部是如何实现的)
递:大问题拆分成子问题的过程
归:碰到终止条件时,陆续给回返值(子问题有解过程)
1.2什么场景下可以使用递归:
*一个大问题可以拆分成为若干个子问题
*原问题和子问题除了数据规模不一样,求解思路完全一样
*存在递归终止条件
例:5!
public class test {
public static void main(String[] args) {
int num=5;
System.out.println(factor(5));
}
//写一个递归函数实现5!
public static int factor(int num){
//先写终止条件
if (num==1){
return num;
}
return num*factor(num-1);
}
}
1.3关于调用栈
方法调用的时候, 会有一个 “栈” 这样的内存空间描述当前的调用关系. 称为调用栈.
每一次的方法调用就称为一个 “栈帧”, 每个栈帧中包含了这次调用的参数是哪些, 返回到哪里继续执行等信息.后面我们借助 IDEA 很容易看到调用栈的内容。
1.4递归练习
例1:按顺序打印一个数字的每一位。例如1234打印出1 2 3 4
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("请输入数字:");
int n = scanner.nextInt();
print(n);
}
public static void print(int n) {
if (n < 0) {//当输入一个负数时,先把它变成整数。
System.out.println("-");
n = -n;
}
if (n > 9) {
print(n / 10);//递归
}
System.out.print(n % 10+" ");//打印个位数
}
例2:递归求1+2+3+。。。+10
public static void main(String[] args) {
System.out.println(add(10));
}
public static int add(int n) {
if(n==1){
return n;
}
return n+add(n-1);
}
例3:写一个递归方法,输入一个非负整数,返回组成它的数字之和. 例如,输入 1729, 则应该返回1+7+2+9,它的和是19
public static void main(String[] args) {
System.out.println(sum(1729));
}
public static int sum(int n) {
//边界
if(n<10){
return n;
}
return n%10 + sum(n/10);
}
例4:求斐波那契数列的第 N 项(1 1 2 3 5 8 13 21 34…)
public static void main(String[] args) {
System.out.print(fib(5));
}
public static int fib(int n) {
//边界
if(n==1||n==2){
return 1;
}
return fib(n-1)+fib(n-2);
}
当我们求 fib(40) 的时候发现, 程序执行速度极慢. 原因是进行了大量的重复运算
class Test {
public static int count = 0; // 这个是类的成员变量. 后面会详细介绍到.
public static void main(String[] args) {
System.out.println(fib(40));
System.out.println(count);
}
public static int fib(int n) {
if (n == 1 || n == 2) {
return 1;
}
if (n == 3) {
count++;
}
return fib(n - 1) + fib(n - 2);
}
}
// 执行结果
102334155
39088169 // fib(3) 重复执行了 3 千万次
通过例4,我们发现递归的效率比较低,因为递归包含大量的重复运算。动态规划就是解决递归重复计算问题。
可以使用循环的方式来求斐波那契数列问题, 避免出现冗余运算。
public static void main(String[] args) {
System.out.println(fib(40));
}
public static int fib(int n) {
int last2 = 1;
int last1 = 1;
int cur = 0;
for (int i = 3; i <= n; i++) {
cur = last1 + last2;
last2 = last1;
last1 = cur;
}
return cur;
}
迭代(循环)效率优于递归,递归效率低,但是递归好写一点。
1.5递归小结
*递归是一种重要的编程解决问题的方式.
*有些问题天然就是使用递归方式定义的(例如斐波那契数列, 二叉树等), 此时使用递归来解就很容易.
*有些问题使用递归和使用非递归(循环)都可以解决. 那么此时更推荐使用循环, 相比于递归, 非递归程序更加高效.
最后
以上就是爱笑纸鹤为你收集整理的JAVA笔记3.方法的使用的全部内容,希望文章能够帮你解决JAVA笔记3.方法的使用所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复