第7章 方法:把复杂程序拆成小块
2026/6/25 16:04:54 网站建设 项目流程

第7章 方法:把复杂程序拆成小块

到目前为止,我们已经能写输入、输出、条件、循环。问题是,如果所有逻辑都写在main方法里,代码会越来越长。

比如一个注册程序:

publicclassRegisterDemo{publicstaticvoidmain(String[]args){Stringphone="13800000000";Stringpassword="123456";intage=20;if(phone==null||phone.length()!=11||!phone.startsWith("1")){System.out.println("手机号不合法");return;}if(password==null||password.length()<6){System.out.println("密码不合法");return;}if(age<18){System.out.println("未满18岁");return;}System.out.println("注册成功");}}

现在还能读。规则再多十条,main 就会变成一大坨。方法就是用来拆分逻辑的。

一、方法是什么

方法是一段有名字的代码。

publicstaticvoidsayHello(){System.out.println("Hello");}

调用:

sayHello();

完整程序:

publicclassMethodDemo{publicstaticvoidmain(String[]args){sayHello();sayHello();}publicstaticvoidsayHello(){System.out.println("Hello");}}

输出:

Hello Hello

方法的价值:

  • 避免重复。
  • 给逻辑起名字。
  • 降低主流程复杂度。
  • 让代码更容易测试。

二、方法的结构

publicstaticvoidsayHello(){System.out.println("Hello");}

可以拆成:

public static 返回值类型 方法名(参数列表) { 方法体 }

第一阶段我们先统一使用public static
publicstatic后面面向对象阶段再深入。

现在重点看:

  • 返回值类型。
  • 方法名。
  • 参数列表。
  • 方法体。

三、参数:方法的输入

没有参数的方法只能做固定事情:

publicstaticvoidprintTom(){System.out.println("Tom");}

有参数的方法更灵活:

publicstaticvoidprintName(Stringname){System.out.println("姓名:"+name);}

调用:

printName("Tom");printName("Jack");

多个参数:

publicstaticvoidprintUser(Stringname,intage){System.out.println("姓名:"+name);System.out.println("年龄:"+age);}

参数是调用方传给方法的数据。方法不要总是依赖写死的数据。

四、返回值:方法的输出

没有返回值用void

publicstaticvoidprintLine(){System.out.println("------");}

有返回值:

publicstaticintadd(inta,intb){returna+b;}

调用:

intresult=add(3,5);System.out.println(result);

返回值让方法可以参与后续计算,而不是只能打印。

不推荐把计算和打印绑死:

publicstaticvoidaddAndPrint(inta,intb){System.out.println(a+b);}

更好:

publicstaticintadd(inta,intb){returna+b;}

外层决定怎么输出。

五、return 的两个作用

1. 返回结果

publicstaticintmax(inta,intb){if(a>=b){returna;}returnb;}

2. 提前结束方法

publicstaticvoidcheckAge(intage){if(age<18){System.out.println("未满18岁");return;}System.out.println("可以注册");}

return 后,方法立即结束。

六、方法命名

方法名要表达动作。

好名字:

  • isValidPhone
  • calculateTotalPrice
  • printMenu
  • readScore
  • findMaxScore

差名字:

  • doIt
  • handle
  • aaa
  • test

布尔返回值方法常用:

publicstaticbooleanisAdult(intage){returnage>=18;}publicstaticbooleanhasPermission(booleanlogin,booleangranted){returnlogin&&granted;}

读起来像问题:

  • 是否成年?
  • 是否有权限?

七、方法重载

同名方法,参数不同,叫重载。

publicstaticintadd(inta,intb){returna+b;}publicstaticintadd(inta,intb,intc){returna+b+c;}publicstaticdoubleadd(doublea,doubleb){returna+b;}

调用时,编译器根据参数选择方法。

System.out.println(add(1,2));System.out.println(add(1,2,3));System.out.println(add(1.5,2.5));

重载适合同一语义、不同参数形式。

不要用重载表达完全不同的事。

八、作用域

方法里的变量只在方法内部有效。

publicstaticvoidtest(){intcount=10;}publicstaticvoidmain(String[]args){// System.out.println(count); // 错误}

代码块里的变量也只在块内有效:

if(true){intvalue=100;}// System.out.println(value); // 错误

变量作用域越小,代码越容易理解。不要把变量提前定义到很大范围。

九、基本类型参数和引用类型参数

基本类型:

publicclassParamDemo{publicstaticvoidmain(String[]args){intage=18;change(age);System.out.println(age);}publicstaticvoidchange(intvalue){value=20;}}

输出:

18

方法里改的是副本,不影响外面的 age。

数组是引用类型:

publicclassArrayParamDemo{publicstaticvoidmain(String[]args){int[]scores={60,70};change(scores);System.out.println(scores[0]);}publicstaticvoidchange(int[]values){values[0]=100;}}

输出:

100

因为方法内外指向同一个数组对象。

第一阶段先记住:基本类型传进去不会改外部变量,数组这类引用类型修改内容会影响外部对象。

十、把注册逻辑拆成方法

publicclassRegisterMethodDemo{publicstaticvoidmain(String[]args){Stringphone="13800000000";Stringpassword="123456";intage=20;if(!isValidPhone(phone)){System.out.println("手机号不合法");return;}if(!isValidPassword(password)){System.out.println("密码不合法");return;}if(!isAdult(age)){System.out.println("未满18岁");return;}System.out.println("注册成功");}publicstaticbooleanisValidPhone(Stringphone){returnphone!=null&&phone.length()==11&&phone.startsWith("1");}publicstaticbooleanisValidPassword(Stringpassword){returnpassword!=null&&password.length()>=6;}publicstaticbooleanisAdult(intage){returnage>=18;}}

主流程现在很清楚:

校验手机号 -> 校验密码 -> 校验年龄 -> 注册成功

每个规则单独放在方法里,后面修改也更方便。

十一、方法的单一职责

一个方法最好只做一件事。

不推荐:

publicstaticvoidvalidateAndSaveAndPrint(Stringphone){}

这个名字已经说明它做太多事:校验、保存、打印。

更好:

publicstaticbooleanisValidPhone(Stringphone){}publicstaticvoidsavePhone(Stringphone){}publicstaticvoidprintSuccess(){}

单一职责的好处:

  • 容易命名。
  • 容易测试。
  • 容易复用。
  • 容易排查。

如果一个方法很难起名,通常说明它职责不清。

十二、方法实战:成绩统计拆分

publicclassScoreMethodDemo{publicstaticvoidmain(String[]args){int[]scores={90,85,70,60};System.out.println("最高分:"+findMax(scores));System.out.println("最低分:"+findMin(scores));System.out.println("平均分:"+calculateAverage(scores));}publicstaticintfindMax(int[]scores){intmax=scores[0];for(intscore:scores){if(score>max){max=score;}}returnmax;}publicstaticintfindMin(int[]scores){intmin=scores[0];for(intscore:scores){if(score<min){min=score;}}returnmin;}publicstaticdoublecalculateAverage(int[]scores){intsum=0;for(intscore:scores){sum+=score;}returnsum*1.0/scores.length;}}

这里还有一个问题:如果 scores 是空数组,会出错。更严谨的版本要加校验。阶段项目里会处理。

十三、常见错误

1. 有返回值却忘记 return

publicstaticintadd(inta,intb){intresult=a+b;}

声明返回 int,就必须 return int。

2. return 类型不匹配

publicstaticintgetAge(){return"18";}

字符串不能作为 int 返回。

3. 参数顺序传错

calculatePrice(count,unitPrice);

如果两个参数都是 int,编译器可能发现不了语义错误。方法名、参数名要清楚,参数太多时后面要用对象封装。

4. 方法太长

一个方法超过几十行,就要考虑能不能拆。

5. 方法名和行为不一致

isValidPhone里不要保存数据。方法名承诺了它只是校验。

十四、本章练习

  1. 写方法isEven(int number),判断偶数。

  2. 写方法max(int a, int b),返回较大值。

  3. 写方法calculateBmi(double height, double weight)

  4. 写方法getScoreLevel(int score),返回优秀、良好、及格、不及格、非法。

  5. 把注册校验拆成三个方法:手机号、密码、年龄。

  6. 给成绩数组写三个方法:最高分、最低分、平均分。

十五、本章总结

方法是组织代码的第一把工具。

你需要掌握:

  • 方法是一段有名字的代码。
  • 参数是输入。
  • 返回值是输出。
  • void 表示没有返回值。
  • return 可以返回结果,也可以结束方法。
  • 方法名要表达意图。
  • 方法重载适合同一语义的不同参数。
  • 变量有作用域。
  • 基本类型和引用类型作为参数表现不同。
  • 方法要尽量单一职责。

下一章是第一阶段项目。我们会把输入、条件、循环、方法组合起来,写一个命令行成绩统计器。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询