1. 方法定义:
Java中的方法类似于其他语言的函数,一般用来完成特定功能的代码片段,一般情况下,定义一个方法需要包含方法头和方法体。
(方法的本意是功能块儿,就是实现某个功能的语句块的集合。我们设计方法的时候,最好保持方法的原子性,就是一个方法只完成一个功能,这样有利于我们后期的拓展。)
-
方法头:
-
修饰符:修饰符是可选择的,告诉编译器如何调用该方法。定义该方法的访问类型。
-
返回值类型:当方法没有返回值时,返回值类型为void,当有返回值时,则需要根据返回值的类型需求定义。
-
方法名:方法的名称。(注:方法签名是方法名加参数表例如 add(a,b))。方法命名规则:
首字母小写,并遵循驼峰原则。 -
参数类型:参数像是一个占位符。当方法被调用时,传递值结合参数,这个值被称为实参或变量。
(参数列表是指方法的参数类型、顺序和参数的个数,参数是可选的,方法可以不包含任何参数。)
- 形参:(形式参数)在方法中被调用的时候用于接收外界输入的数据。
- 实参:(实际参数)调用方法时实际传给方法的数据。
-
-
方法体:方法体包含具体的语句,定义该方法的功能。
-
return:方法存在返回值时,一定要用return将值返回到返回值。
2. 方法结构:
修饰符 返回值类型 方法名 (参数类型 参数名){
方法体;
}
3. 方法的调用方法:对象名.方法名(实参列表);
java支持两种调用方式,是根据方法是否返回值来选择。
-
当方法返回一个值时,方法调用通常被当做一个值。例如:
int larger = max(30,40);
-
如果方法返回值是void,方法调用一定是一条语句。例如:
System.out.println("Hello,world!");
4. 定义方法及调用示例:
public class test {
public static void main(String[] args) {
//方法调用:首先定义一个变量larger用于存储max方法的返回值,并且输出两个数字中较大的那个值
int larger = max(5,10);
System.out.println(larger);
}
//设计一个比较大小的方法
public static int max(int num1,int num2){
int result;
//第一个if语句用于判断两个参数相等的情况
if(num1 == num2){
return 0;
}
//第二个if语句用于比较两个参数的大小,并且总是将大的数存入result这个变量
if(num1 > num2){
result = num1;
}else{
result = num2;
}
//result 作为返回值被返回
return result;
}
}
5. 方法的重载;:
方法的重载指的是在一个类中,有同样的变量名字,但是形参却不相同的函数。
方法重载的规则:
- 方法名必须相同。
- 参数列表必须不同(个数或者类型、不同参数排列顺序不同。)
- 方法的返回类型可以相同也可以不相同。
- 仅仅返回类型不同不足以成为方法的重载。
(实现理论:方法名称相同时,编译器会根据调用方法的参数个数、参数类型等逐个去匹配,以选择相对应的方法,如果匹配失败则编译器报错。)
public class test {
public static void main(String[] args) {
//方法调用:首先定义一个变量larger用于存储max方法的返回值,并且输出两个数字中较大的那个值
int larger = max(5,10);
System.out.println(larger);
double larger01 = max(2.3,3);
System.out.println(larger01);
//调用的两个方法虽然名字相同但是编译器匹配的却是根据我们提供的数字类型匹配的合适类型的方法。
}
//double类型数字比较大小的方法
public static double max(double num1,double num2){
double result01;
if(num1 == num2){
return 0;
}
if(num1 > num2){
result01 = num1;
}else{
result01 = num2;
}
return result01;
}
//int类型数字比较大小的方法
public static int max(int num1,int num2){
int result02;
if(num1 == num2){
return 0;
}
if(num1 > num2){
result02 = num1;
}else{
result02 = num2;
}
return result02;
}
}
方法的重载我们可以理解为一个广义的方法,即实现的功能相同一组方法,但是由于方法要求实参和形参类型及数量需要相对应。为了避免定义过多的重复功能的方法名,对于变量类型需求不同,或者变量的数量不同时,我们则可以利用方法重载去实现只用一个方法名,就可以实现各种类型,各种数量的变量之间的计算或者执行。
6. 命令行传参:
有时时候我们希望运行一个程序时再传递给他值,这要靠传递main()方法实现。(暂且记录到这里,主要需要记住在cmd中想要使用命令行传参,运行class文件需要找到其包的路径,由于目前就阶段使用相对较少具体的暂时不多说了。)
7. 可变参数
从jdk1.5开始,java支持传递同类型可变参数给一个方法。
在方法中,在指定参数类型后面加一个省略号。
但是一个方法只可以指定一个可变参数,并且它必须是方法的最后一个参数。任何普通的参数必须在它之前声明。
public class Demo {
public static void main(String[] args) {
printMax(0,5,3,8);//我们使用此方法可以找到任意数量数组中最大的值
printMax(new double[]{1,2,3});//方然我们也可以在实参中新建立一个数组,不过idea会提醒这是多余的操作,但是依旧可以运行。
}
public static void printMax(double...i){
if(i.length == 0){
System.out.println("没有数字");
}
double result = 0;
for (int j = 0; j < i.length; j++) {
if(i[j] > result){
result = i[j];
}
}
System.out.println("最大的数字是:"+result);
}
}
8. 递归(!!重点)
我们很容易理解A方法调用B方法,例如在main方法中调用其他方法。但是递归则是A方法调用A方法,即方法的自我调用。
利用递归可以用简单的程序来解决一些复杂的问题,它通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解,递归的能力在于用有限的语句定义对象的无限集合。
递归结构包含两个部分:
- 递归头:表示什么时候不调用自身方法,如果没有头将陷入死循环。
- 递归体:表示什么时候需要调用自身方法。
(千万不要将方法的自我调用想的很简单,否则很容易死循环)
方法自我调用的错误示范:
Demo test = new Demo();
test.test();
public void test(){
test()
}
这种方法调用是没意义的。
正确的递归需要有边界条件,来判断什么时候结束。
可以实现递归是由于java的栈机制,每进行一次方法的自我调用,可以认为在栈中叠了一层,也因侧只有基数较小的时候可以使用递归,大计算最好不要这样做,否则计算机可能会卡住。
下面是递归的示例:
public class Demo {
public static void main(String[] args) {
//递归方法的调用
System.out.println(f(5));//运行得到120,确实为5的阶乘为正确答案
}
//阶乘方法
public static int f(int n){
//递归头:即递归的边界条件
if(n == 1){
return 1;
}else{
//递归体 参数值大于边界条件,则一直进行自我调用
return n*f(n - 1);
}
}
}
综合流程控制以及方法的学习,分享一下老师留的作业:写一个计算器,实现两个数的加减乘除运算,并且能够循环接收新的数据。
import java.util.Scanner;
public class Cal {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("请输入开始或退出:");
String str = scanner.nextLine();//输入字符串控制程序开始
Scanner scanner01 = new Scanner(System.in);
double num1 = scanner01.nextDouble();//输入第一个数字
Scanner scanner02 = new Scanner(System.in);
String m = scanner02.nextLine();//输入加减乘除任意一种算法
Scanner scanner03 =new Scanner(System.in);
double num2 = scanner03.nextDouble();//输入第二个数字
while (!str.equals("退出")){
if (m.equals("+")) {
System.out.println(add(num1,num2));
}else if (m.equals("-") ){
System.out.println(sub(num1,num2));
}else if (m.equals("*")) {
System.out.println(mul(num1, num2));
}else if ( m.equals("/")) {
System.out.println(div(num1, num2));
}else{
System.out.println("输入的符号不合法");
}
System.out.println("输入任意键继续,输入退出则退出程序");
str= scanner.nextLine();//重新输入str的值以保证能够重新循环或者是退出循环
if(str.equals("退出")){
continue;
}
num1 = scanner01.nextDouble();//输入第一个数字
m = scanner02.nextLine();//输入加减乘除母
num2 = scanner03.nextDouble();//输入第二个数字
}
scanner.close();
scanner01.close();
scanner02.close();
scanner03.close();
}
//加法
public static double add(double a, double b) {
return a + b;
}
//减法
public static double sub(double a,double b) {
return a - b;
}
//乘法
public static double mul(double a,double b){
return a * b;
}
//除法
public static double div(double a,double b){
return a / b;
}
}
9. 小结
方法部分呢就先总结到这里了,这一部分感觉是目前学到的内容里面最有趣的部分,就拿我完成老师作业这个过程为例子分享一下吧。
虽然这只能计算两个数字的加减乘除运算,但是通过自己整合自己学到的知识,一点点改进并成功达到目标这个过程还是很开心的,虽然中间也遇到过很多问题,例如:我第一版使用了90多行代码,却只能实现用户先选择加减乘除运算再输入两个数字。再例如scanner.close()放在循环内部会导致输入加减乘除符号以后立刻报错,后来通过测试才发现原来这回中断循环,再比如,scanner连续使用只能输入同一类型的字符,于是在用户输入数字以及加减乘除这里便每次输入一次内容就打开一个scanner才完成能够按照顺序输入数字-(+、-、*、/)-数字。不过最终都解决了,虽然运行起来略显笨拙,但是我相信,等学会更多知识,我还可以做的更好的。
嘛,其实写代码,感觉最开心的就是你写出了想要的效果那个时刻,以及你用了更少行代码完成了更多任务时候,希望这种对待编程的态度可以保持下去,自己!!加油呐!!
最后附上学习网址:https://www.kuangstudy.com/学相伴
还有就是,如果发现以上内容我哪里说错了,还请各位批评指正。