一、方法
1.静态方法
理解:特定功能的代码块
好处:解决代码的冗余
语法结构:
访问修饰符 static 返回值类型 方法名([参数列表]){
...代码块...
}
分类:
无参数无返回值的方法
带参数的方法
带返回值的方法
2.无参数无返回值的方法
语法结构:
public static void 方法名(){
...代码块
}
注意:
1.public是访问修饰符的一种,表示公有的
2.void表示无返回值(关键字)
3.方法在类中声明
4.方法与方法之间是平级关系
5.方法没被调用,就是个摆设
实例1:
javapublic class Test{ public static void main(String[] args){ //调用方法 //Test01.run(); //Test01.run(); //Test01.play(); //Test01.run(); //Test01.play(); //Test01.run(); //调用方法 ps:只有在同一个类才行 run(); run(); play(); run(); play(); run(); } public static void run(){ System.out.println("111"); } public static void play(){ System.out.println("222"); } }
实例2:用"*"打印三角形(方法版)
javapublic class Test{ public static void main(String[] args){ printStar(); } public static void printStar(){ for(int i = 0;i<5;i++){ for(int j = 0;j<=i;j++){ System.out.print("*"); } System.out.println(); } }
3.带参数的方法
语法结构:
public static void 方法名(参数列表){
...代码块...
}
注意:
- .形式参数/形参:声明方法时规定的参数
- 形参必须声明类型
- 形参属于该方法的变量,作用域就在该方法内,形参也是局部变量
- 局部变量:方法里声明的变量
- 实际参数/实参:调用方法时传入的数据
- 实参和形参的类型必须兼容
- 实参和形参可以有多个,用逗号分割
案例1:设计一个方法,打印三角形,三角形的行数由调用方传入
javapublic class Test{ public static void main(String[] args){ printStar(5); } public static void printStar(int num){ for(int i = 0;i<num;i++){ for(int j = 0;j<=i;j++){ System.out.print("*"); } System.out.println(); } }
案例2:设计一个方法,传入两个int值,输出最大值
javapublic class Test{ public static void main(String[] args){ getMax(10,20); } public static void getMax(int a,int b){ int max=(a>b)?a:b; System.out.println("最大值为:"+ max); } }
4.带返回值的方法
语法结构:
public static 返回值类型 方法名([参数列表]){
...代码块...
return 数据;//1.结束当前方法 2.将数据返回给调用方
}
注意:
- 带返回值的方法有没有参数要看具体需求
- 声明方法时需要设置返回值类型
- return后接的是需要返回的具体数据
- 方法功能单一性(一个方法的功能不要过于强大)
- 方法声明时规定的返回值类型 和 return后的数据 必须兼容
- 返回值只能有一个,如果想返回多个值就必须使用数组、集合、...
案例:设计一个方法,传入两个int值,返回最大值 在控制台输入是三个int值,输出最大值
javaimport java.util.Scanner; public class Test{ public static void main(String[] args){ Scanner scan = new Scanner(System.in); System.out.println("输入第一个数:"); int a = scan.nextInt(); System.out.println("输入第二个数:"); int b = scan.nextInt(); System.out.println("输入第三个数:"); int c = scan.nextInt(); int max=getMax(a,b); max=getMax(max,c); System.out.println("最大值为:"+max); } public static int getMax(int a,int b){ int max=(a>b)?a:b; return max; } }
二、方法的重载
概念:方法之间的关系
条件:
- 在同一个类中
- 方法名必须一致
- 参数列表的个数或者类型不一致
- 与返回值无关
好处:系统会根据实参类型自动匹配到对应的方法中
应用场景:在同一个类中,多个方法功能大概一致,但是细节实现不一致,就可以考虑使用重载
设计方法的步骤:
- 考虑方法名(见名知意)
- 考虑形参(几个?类型?)
- 考虑返回值(需不需要?返回值类型)
三、方法的递归
含义:方法调用方法自身
注意:递归是一种程序设计的思想
经验:
- 找规律:什么情况下方法应该调用方法自身
- 找出口:什么情况下应该解决该方法
案例1:设计一个方法,传入一个int值n,求n的阶乘
- 找规律:n!=(n-1)!*n
- 找出口:1!=1
javapublic class Test{ public static void main(String[] args){ int num = getFactorial(5); System.out.println(num); } public static int getFactorial(int n){ if(n != 1){ return getFactorial(n-1) * n; }else{ return 1; } } }
运行逻辑:
主方法向getFactorial()传入数据"5"
在getFactorial方法中开始判断
5!=1 ---> 执行getFactorial(5-1) * 5 ---> 调用getFactorial(4) ... 直到getFactorial(1) ---> return 1 (同时释放getFactorial(1)方法) ---> getFactorial(1)*2(释放getFactorial(2)方法) ... return getFactorial(4) * 5 =120
打印num。
案例2:不死神兔问题:有1对兔子,从出生后的第3个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子,假如兔子都不死,问第n个月有几对兔子,设计一个方法,传入月份,获取当月兔子的对数
- 找规律:当月兔子的对数等于上个月+上上个月兔子的对数
- 找出口:1月或2月都是1对兔子
javaimport java.util.Scanner; public class Test{ public static void main(String[] args){ Scanner scan=new Scanner(System.in); System.out.println("请输入查询的月份"); int month = scan.nextInt(); int sum=getRabbit(); System.out.println(month+"月,一共有"+sum+"对兔子"); } public static int getRabbit(int month){ if(month==1 || month==2){ return 1; }else{ return getRabbit(month-1)+getRabbit(month-2); } } }
扩展:
不死神兔的数据:1,1,2,3,5,8,13,21...
这种数列叫做斐波那契数列/黄金分割数列
该数列相邻两个数的比例越往后越趋近于0.618
四、一维数组
理解:一组数据的容器
声明:
数据类型[] 数组名;
数据类型 数组名[];
概念:
- 数组是引用数据类型
- 数组中的数据也叫做元素
- 元素都是编号也叫做下标/索引
- 下标从0开始
- 数组元素在内存中开辟的空间是连续的
- 数组一旦初始化成功,长度不可变(意味着数组不能添加和删除)
数组的初始化:
静态初始化:元素由程序员指定,长度由系统分配
动态初始化:长度由程序员指定,元素由系统分配
整数类型默认值:0
浮点类型默认值:0.0
字符类型默认值:' '
布尔类型默认值:false
引用类型默认值:null(空)
静态初始化
javapublic class Test{ public static void main(String[] args){ //设置静态初始化 //1.String[] names =new String[]{"张三","李四","王五","赵六"}; //2.String[] names; // names=new String[]{"张三","李四","王五","赵六"}; //3. String[] names={"张三","李四","王五","赵六"}; //修改 names[1]="小明"; String str=names[1]; System.out.println(str); //获取下标长度 int len=names.lengthl System.out.println("长度为:"+len); //遍历1. for(int i=0,i<names.length;i++){ System.out.println(names[i]); } //遍历2. for(String element:names){ System.out.println(element); } } }
遍历使用for与foreach的使用:
- 遍历数组时,使用到下标 -- for循环
- 遍历数组时,不使用到下标 -- foreach
动态初始化
javapublic class Test{ public static void main(String[] args){ //设置动态初始化 //1.String[] names=new String[4]; //2. String[] names; names=new String[4]; //设置内容 names[0]="张三"; names[1]="李四"; names[2]="王五"; names[3]="赵六"; String str=names[1]; System.out.println(str); //获取下标长度 int len=names.lengthl System.out.println("长度为:"+len); //遍历1. for(int i=0,i<names.length;i++){ System.out.println(names[i]); } //遍历2. for(String element:names){ System.out.println(element); } } }
在设置 下标上的元素时,如果下标超出开辟的空间数,会报ArrayIndexOutOfBoundsException数组下标越界异常。
一维数组案例:创建一个int类型的数组,长度由用户指定,数据由用户输入,输入完毕后获取最大值并输出
javaimport java.util.Scanner; public class Test{ public static void main(String[] args){ Scanner scan= new Scanner(System.in); System.out.println("请输入数组长度:"); int[] arr=scan.nextInt(); for(int i=0;i<arr.length;i++){ System.out.println("请输入第"+i+"个元素:"); int num=scan.nextInt(); arr{i}=num; } int max=arr[0]; for(int i=1;i<arr.length;i++){ if(max<arr[i]){ max=arr[i]; } } System.out.println("最大值为:"+max); } }
小结:
- 初始化时只知道元素,就使用静态初始化
- 初始化时只知道长度,就使用动态初始化
- int类型的数组为引用数据类型,数组中的元素是基本数据类型