4. Java核心概念:方法与数组详解
经过前面几节的学习,你已经掌握了 Java 的基础语法。现在我们要学习两个让程序变得更强大的工具:方法和数组。
想象一下:
- 方法就像生活中的"技能"——比如做饭、洗衣服,学会一次就能重复使用
- 数组就像"储物柜"——能够整齐地存放一组相同类型的物品
通过这节课,你将学会:
- 方法的使用 - 把重复的代码变成可重用的"技能包"
- 数组的操作 - 高效管理一组相关的数据
- 实际应用 - 结合方法和数组解决实际问题
掌握这两个概念后,你的程序将变得更简洁、更强大!
一、方法:程序中的"技能包"
还记得我们之前写的 System.out.println()
吗?其实 println
就是一个方法!它被别人写好了,我们只需要调用就能使用。
现在,我们要学会自己创造这样的"技能包"。
想象你学会了做蛋炒饭:
- 第一次:摸索着做,可能会失败
- 掌握后:每次想吃都能快速做出来
- 教朋友:把步骤告诉别人,他们也能做
方法就是这样:写一次,到处使用!
使用方法的三大好处:
- 避免重复 - 相同的代码不用写很多遍
- 便于维护 - 修改功能时只需要改一个地方
- 程序清晰 - 复杂功能分解成小块,容易理解
1. 方法的定义:创造你的第一个"技能包"
定义方法就像制作一个工具,需要说明这个工具的各个部分:
修饰符 返回值类型 方法名(参数类型 参数名1, 参数类型 参数名2, ...) {
// 方法体:具体要做的事情
return 返回值; // 如果有返回值的话
}
让我们用生活中的例子来理解每个部分:
1. 修饰符 - 这个技能的"使用权限"
public
:任何人都能学会和使用static
:不需要特殊准备就能直接使用
2. 返回值类型 - 技能执行后的"成果"
void
:只做事,不返回结果(像洗碗)int
:返回一个整数(像数人数)String
:返回一段文字(像取名字)
3. 方法名 - 技能的"名称"
- 用小驼峰命名法:
calculateAge
、printScore
- 名字要能说明这个方法是做什么的
4. 参数列表 - 技能需要的"原料"
- 比如做蛋炒饭需要鸡蛋和米饭
(int age, String name)
表示需要年龄和姓名
5. 方法体 - 具体的"操作步骤"
- 大括号
{}
里面写具体要做的事情
2. 方法的调用:使用你的"技能包"
定义好方法后,就可以在需要的地方"使用"这个技能了!
在同一个类中调用(最常见)
方法名(参数值); // 比如:sayHello("张三");
调用有返回值的方法
数据类型 变量名 = 方法名(参数值);
// 比如:int result = add(3, 5);
直接使用返回值
System.out.println(add(3, 5)); // 直接打印计算结果
就像你学会做蛋炒饭后,想吃的时候就可以"调用"这个技能一样简单!
3. 带返回值的方法:会"交作业"的技能
有些方法不仅会做事,还会给你一个"结果"。就像你问计算器 2+3 等于多少,它会告诉你答案是 5。
- 问朋友现在几点:他会告诉你时间(返回 String)
- 数一下班里有多少人:你会得到一个数字(返回 int)
- 计算考试平均分:你会得到分数(返回 double)
在 Java 中,用 return
语句来"交出"结果。
示例:制作一个"计算面积"的技能包
public class ExampleMethods {
public static void main(String[] args) {
int width = 3;
int height = 5;
int area = getArea(width, height); // 调用 getArea 方法,并将返回值赋给 area
System.out.println("矩形的宽度是: " + width);
System.out.println("矩形的高度是: " + height);
System.out.println("矩形的面积是: " + area);
}
// 定义一个计算矩形面积的方法
// 修饰符: public static
// 返回值类型: int (因为面积是整数)
// 方法名: getArea
// 参数列表: int x (代表宽度), int y (代表高度)
public static int getArea(int x, int y) {
int temp = x * y; // 计算面积
return temp; // 返回计算结果
}
}
运行结果:
(原手册中
Example20
的内容)
4. void 方法:只做事不"交作业"的技能
有些技能只需要完成任务,不需要给你结果。比如洗碗、打扫卫生、打印信息等。
void
的意思是"空",表示没有返回值- 这类方法主要用来:打印信息、修改数据、执行操作等
- 不需要
return
语句,或者可以用return;
提前结束
示例:制作一个"打招呼"的技能包
public class VoidMethodDemo {
public static void main(String[] args) {
greetUser("张三"); // 调用 greetUser 方法
greetUser("李四");
}
// 定义一个打印问候语的方法
public static void greetUser(String name) {
System.out.println("你好, " + name + "! 欢迎学习Java。");
// 这里不需要 return 语句,或者可以使用 return; 提前结束
}
}
5. 方法的重载 (Overloading)
方法重载是指在一个类中,可以定义多个同名的方法,但这些方法的参数列表必须不同。参数列表的不同可以体现在:
- 参数的个数不同。
- 参数的类型不同。
- 参数的顺序不同 (如果类型也不同的话)。
示例:不同参数的求和方法
public class MethodOverloadDemo {
public static void main(String[] args) {
// 调用不同参数的 add 方法
int sum1 = add(1, 2); // 调用 add(int, int)
int sum2 = add(2, 2, 3); // 调用 add(int, int, int)
double sum3 = add(1.2, 2.3); // 调用 add(double, double)
System.out.println("sum1 (1 + 2) = " + sum1);
System.out.println("sum2 (2 + 2 + 3) = " + sum2);
System.out.println("sum3 (1.2 + 2.3) = " + sum3);
}
// 实现两个整数相加
public static int add(int a, int b) {
System.out.println("调用了 add(int a, int b) 方法");
return a + b;
}
// 实现三个整数相加 (参数个数不同)
public static int add(int a, int b, int c) {
System.out.println("调用了 add(int a, int b, int c) 方法");
return a + b + c;
}
// 实现两个小数相加 (参数类型不同)
public static double add(double a, double b) {
System.out.println("调用了 add(double a, double b) 方法");
return a + b;
}
}
运行结果:
(原手册中
Example21
的内容,略作修改以显示调用的是哪个方法)
- 编写一个方法,接收一个整数作为参数,判断这个数是奇数还是偶数,并打印结果 (例如:“XX是奇数” 或 “XX是偶数”)。这个方法应该没有返回值 (
void
)。 - 重载上一个方法,使其可以接收一个
double
类型的参数,并判断其整数部分是奇数还是偶数。
二、数组:程序中的"储物柜"
想象一下学校的储物柜:每个柜子都有编号(0号、1号、2号…),可以放相同类型的物品。数组就是这样的"电子储物柜"!
- 固定大小:就像储物柜总数是固定的
- 相同类型:一个数组只能存放同种类型的数据
- 有序排列:每个位置都有编号(从 0 开始)
- 快速访问:通过编号可以直接找到想要的数据
比如存放班级同学的分数:[85, 92, 78, 96, 88]
1. 数组的声明:预订你的"储物柜"
就像去租储物柜要先登记,使用数组也要先"声明"。
推荐写法(清晰易读)
数据类型[] 数组名;
常见例子:
int[] scores; // 存放分数的数组
String[] names; // 存放姓名的数组
double[] heights; // 存放身高的数组
重要提醒:
现在只是"预订"了储物柜,但还没有真正拿到钥匙!
- 声明后的数组值是
null
(空) - 必须进行"初始化"才能真正使用
2. 数组的创建与初始化:真正拿到"储物柜"
现在要真正创建储物柜,有两种方式:
方式一:先定大小,后放东西(动态初始化)
就像先租了 5 个空储物柜,以后再决定放什么:
数组名 = new 数据类型[长度];
实际例子:
int[] scores = new int[5]; // 5个位置存分数
String[] names = new String[10]; // 10个位置存姓名
自动默认值:
- 整数数组:每个位置自动填入
0
- 小数数组:每个位置自动填入
0.0
- 字符串数组:每个位置自动填入
null
(空) - 布尔数组:每个位置自动填入
false
示例:动态初始化并查看默认值
public class ArrayDefaultValues {
public static void main(String[] args) {
int[] intArray = new int[3];
double[] doubleArray = new double[2];
String[] stringArray = new String[2];
System.out.println("intArray[0]: " + intArray[0]); // 输出 0
System.out.println("doubleArray[0]: " + doubleArray[0]); // 输出 0.0
System.out.println("stringArray[0]: " + stringArray[0]); // 输出 null
}
}
方式二:边建柜子边放东西(静态初始化)
就像直接说"我要3个柜子,分别放苹果、香蕉、橙子":
数据类型[] 数组名 = {元素1, 元素2, 元素3, ...};
实际例子:
int[] scores = {85, 92, 78, 96, 88}; // 直接存入5个分数
String[] fruits = {"苹果", "香蕉", "橙子"}; // 直接存入3种水果
double[] heights = {175.5, 168.2, 180.1}; // 直接存入3个身高
优点: 如果你已经知道要存什么数据,这种方式更简单直接!
public class StaticInitArray {
public static void main(String[] args) {
int[] arr = {1, 2, 3, 4}; // 静态初始化
//依次打印数组中每个元素的值
System.out.println("arr[0]: " + arr[0]);
System.out.println("arr[1]: " + arr[1]);
System.out.println("arr[2]: " + arr[2]);
System.out.println("arr[3]: " + arr[3]);
}
}
3. 访问数组元素
数组中的每个元素都有一个唯一的索引 (index),用于标识其在数组中的位置。索引从 0 开始,到 数组长度 - 1
结束。
通过 数组名[索引]
的方式来访问或修改指定索引位置的元素。
示例:访问和修改数组元素 (原 Example22 和 Example23 结合并修正)
public class AccessArray {
public static void main(String[] args) {
// 动态初始化一个长度为3的整数数组
int[] arr = new int[3]; // 元素默认值为 0, 0, 0
System.out.println("初始化后:");
System.out.println("arr[0] = " + arr[0]); // 访问第一个元素 (索引为0)
System.out.println("arr[1] = " + arr[1]); // 访问第二个元素 (索引为1)
System.out.println("arr[2] = " + arr[2]); // 访问第三个元素 (索引为2)
// 为数组元素赋值
arr[0] = 10;
arr[1] = 20;
arr[2] = 30;
// arr[3] = 40; // 如果尝试访问或赋值超出范围的索引,会抛出 ArrayIndexOutOfBoundsException 错误
System.out.println("\n赋值后:");
System.out.println("arr[0]: " + arr[0]);
System.out.println("arr[1]: " + arr[1]);
System.out.println("arr[2]: " + arr[2]);
// 获取数组的长度
System.out.println("\n数组的长度是: " + arr.length);
}
}
运行结果 (类似原 Example22 和 Example23 的结合):
(上图显示的是默认值,赋值后的结果会是10, 20, 30)
0
到 数组长度 - 1
的有效范围内。如果使用的索引超出了这个范围(小于0或大于等于数组长度),程序在运行时会抛出 ArrayIndexOutOfBoundsException
异常,导致程序中断。4. 数组的长度
可以使用 数组名.length
属性来获取数组的长度(即数组中元素的个数)。这是一个属性,不是方法,所以后面没有括号 ()
。
int[] numbers = {10, 20, 30, 40, 50};
int len = numbers.length; // len 的值是 5
System.out.println("数组 numbers 的长度是: " + len);
5. 遍历数组
遍历数组是指按顺序访问数组中的每一个元素。最常用的方式是使用 for
循环。
示例:使用 for 循环遍历数组
public class TraverseArray {
public static void main(String[] args) {
String[] names = {"Alice", "Bob", "Charlie", "David"};
System.out.println("学生名单:");
for (int i = 0; i < names.length; i++) { // i 从 0 开始,到 names.length - 1 结束
System.out.println("索引 " + i + ": " + names[i]);
}
}
}
基础练习:
- 创建一个整数数组,存放你和4个同学的年龄
- 用方法计算平均年龄,并输出结果
- 找出年龄最大的人
进阶挑战:
- 写一个方法,接收一个整数数组,返回数组中的最大值
- 写一个方法,打印数组中的所有元素(用逗号分隔)
- 结合方法和数组,制作一个简单的成绩管理系统
本节小结
✅ 方法的定义和调用 - 会创建自己的"技能包"
✅ 带返回值的方法 - 会制作"有结果"的技能
✅ void 方法 - 会制作"只做事"的技能
✅ 方法重载 - 同名方法可以有不同参数
✅ 数组的创建 - 会使用程序中的"储物柜"
✅ 数组的访问 - 会存取储物柜中的数据
现在你的程序可以更加智能和高效了!
下一步: 继续学习字符串、集合等更高级的概念,让你的程序功能更加强大!