元数据卡
- 前置知识:变量与类型(第2章)、控制流(第4章)
- 预计时间:15 分钟
- 完成标志:能够定义一个无参数方法并在 main 中调用它
你的进度
老陈的兵器铺里今天特别安静。你推门进去,看见他正在炉前凝神——不是在打铁,是在等你。
"你学会了变量,"他头也不抬,"学会了判断,学会了循环。你已经能写出一直在跑、一直在改变的程序了。"
"但你还只会把代码写成一整块——从上到下,像竹竿一样。如果你想做两件不一样的事,你得把同样的代码写两遍。如果想做一件复杂的事,你得把所有步骤揉在一个大熔炉里。"
他拿起一把锤子敲了一下铁砧:"一味蛮干。你见过哪个铁匠打一把剑要从挖矿开始?"
你的任务
你的第一个问题:你的代码越来越长,读着后面的就忘了前面;你想让一段逻辑反复用,只能复制粘贴——而复制粘贴是 bug 之源。
这章的任务就是学会拆解——把一大段重复的逻辑打包成一个有名字的小任务,叫它一声它就帮你做完。
第一幕:重复的噩梦
假设你在写一个程序:显示三次欢迎信息。
public class Welcome {
public static void main(String[] args) {
System.out.println("====== 欢迎来到变量村 ======");
System.out.println("冒险者,你准备好了吗?");
System.out.println("====== 欢迎来到变量村 ======");
System.out.println("再次提醒:带好你的干粮和水");
System.out.println("====== 欢迎来到变量村 ======");
System.out.println("最后说一次:前路危险!");
}
}def main():
print("====== 欢迎来到变量村 ======")
print("冒险者,你准备好了吗?")
print("====== 欢迎来到变量村 ======")
print("再次提醒:带好你的干粮和水")
print("====== 欢迎来到变量村 ======")
print("最后说一次:前路危险!")
if __name__ == "__main__":
main()#include <iostream>
#include <string>
using namespace std;
int main() {
cout << "====== 欢迎来到变量村 ======" << endl;
cout << "冒险者,你准备好了吗?" << endl;
cout << "====== 欢迎来到变量村 ======" << endl;
cout << "再次提醒:带好你的干粮和水" << endl;
cout << "====== 欢迎来到变量村 ======" << endl;
cout << "最后说一次:前路危险!" << endl;
return 0;
}语言:Java 21 如何运行:保存为 Welcome.java,运行 javac Welcome.java && java Welcome预期输出:
====== 欢迎来到变量村 ======
冒险者,你准备好了吗?
====== 欢迎来到变量村 ======
再次提醒:带好你的干粮和水
====== 欢迎来到变量村 ======
最后说一次:前路危险!你的第一反应可能是:"不对,我应该写一个循环。"好,用循环改写:
public class Welcome {
public static void main(String[] args) {
for (int i = 0; i < 3; i++) {
System.out.println("====== 欢迎来到变量村 ======");
}
System.out.println("冒险者,你准备好了吗?");
System.out.println("再次提醒:带好你的干粮和水");
System.out.println("最后说一次:前路危险!");
}
}def main():
for i in range(0, 3):
print("====== 欢迎来到变量村 ======")
print("冒险者,你准备好了吗?")
print("再次提醒:带好你的干粮和水")
print("最后说一次:前路危险!")
if __name__ == "__main__":
main()#include <iostream>
#include <string>
using namespace std;
int main() {
for (int i = 0; i < 3; i++) {
cout << "====== 欢迎来到变量村 ======" << endl;
}
cout << "冒险者,你准备好了吗?" << endl;
cout << "再次提醒:带好你的干粮和水" << endl;
cout << "最后说一次:前路危险!" << endl;
return 0;
}好多了。但假设——这个欢迎横幅要出现在十个不同的地方,每种场合的文字不同。
你发现自己还在复制三行重复的结构。真正的问题是:你没法把一个"动作"打包成一个有名字的东西。
而方法(method)就是那个"有名字的东西"。
第二幕:定义你的第一个方法
打开你的编辑器。别复制,自己打一遍——手打才能感觉到节奏:
public class Blacksmith {
public static void main(String[] args) {
showBanner();
System.out.println("老陈师傅正在打铁。");
showBanner();
}
// ↓↓↓ 看你师傅这里 ↓↓↓
static void showBanner() {
System.out.println("====== 铁匠铺 ======");
System.out.println(" 老陈在此");
System.out.println("====================");
}
}def show_banner():
print("====== 铁匠铺 ======")
print(" 老陈在此")
print("====================")
def main():
show_banner()
print("老陈师傅正在打铁。")
show_banner()
if __name__ == "__main__":
main()#include <iostream>
#include <string>
using namespace std;
void showBanner() {
cout << "====== 铁匠铺 ======" << endl;
cout << " 老陈在此" << endl;
cout << "====================" << endl;
}
int main() {
showBanner();
cout << "老陈师傅正在打铁。" << endl;
showBanner();
return 0;
}语言:Java 21 如何运行:javac Blacksmith.java && java Blacksmith预期输出:
====== 铁匠铺 ======
老陈在此
====================
老陈师傅正在打铁。
====== 铁匠铺 ======
老陈在此
====================看见了吗?你只是在 main 里调用了两次 showBanner(),程序就跑到了另一个地方,执行里面的三条 println,再回来。
方法的基本语法:
static void 方法名() {
// 你想做的事
}def 方法名():
# 你想做的事void 方法名() {
// 你想做的事
}拆解各部分的含义:
- Java 的
static:现在先记住——"这个方法属于类本身,不需要创建对象就能调用"。第7章面向对象时会拆解它。 void:这个方法不返回任何东西。它做完了事,没有"成果"给你。- 方法名:小驼峰命名(Java/C++),动词开头。
showBanner、calculateDamage、isReady。
Python 差异:
阿花从侧边探过头:"Python 里方法定义不用那么啰嗦。"
pythondef show_banner(): print("====== 铁匠铺 ======") print(" 老陈在此") print("====================") # 调用 show_banner()Python 用
def关键字,没有static和返回类型声明。方法名用蛇形命名(snake_case)。不需要用分号——但这对你来说是好事还是坏事?答案是:省了打字,丢了视觉边界感。
调用方法时发生了什么?
- Java 程序从
main开始执行 - 遇到
showBanner(),暂停main - 跳转到
showBanner的代码,逐行执行 - 执行完毕,跳回
main中刚才暂停的地方,继续往下走
就像你走到铁匠铺,对着老陈喊一声"打把剑",他停下来接活,干完了你再继续赶路。
旅人笔记
- 方法 = 把一段逻辑打包成一个有名字的小任务
- 定义方法时用
static void 方法名()(Java/C++)或def 方法名()(Python) - 调用方法时只需写
方法名() - 方法内部可以调用另一个方法,但方法不能嵌套定义(别在方法里写方法)
→ 下一步
你已经学会了把代码打包成方法。但你会发现一个问题:showBanner() 只能打印固定的内容——如果我想让方法接收不同的材料,打出不同名字的兵器呢?
下一节 参数传递与返回值,我们来解决这个问题。