Day 9:Java 方法重载 · 值传递 · 方法拆分

看懂今天要学什么

方法重载  →  方法名相同,参数不同,Java 帮你选对那个
值传递    →  传的是“副本”,不是原件(基本类型更明显)

方法拆分  →  一个方法只做一件事,main 只负责“指挥”

1. 方法重载(Overload)

1.1 一句话

同一个类里,方法名相同,参数列表不同 → 构成重载。

Java 看的是:参数个数 / 类型 / 顺序,不看返回值类型。

1.2 什么叫“参数列表不同”

情况是否算重载例子

参数个数不同

add(int a, int b) 和 add(int a, int b, int c)

参数类型不同

add(int a, int b) 和 add(double a, double b)

参数顺序不同

print(String s, int n) 和 print(int n, String s)

只有返回值不同

int f() 和 void f() → 编译报错

只有参数名不同

add(int a, int b) 和 add(int x, int y) → 不算

1.3 一眼能懂的例子:计算器

public class Calculator {

    // 两个 int 相加
    public static int add(int a, int b) {
        System.out.println("调用:两个 int");
        return a + b;
    }

    // 三个 int 相加(个数不同 → 重载)
    public static int add(int a, int b, int c) {
        System.out.println("调用:三个 int");
        return a + b + c;
    }

    // 两个 double 相加(类型不同 → 重载)
    public static double add(double a, double b) {
        System.out.println("调用:两个 double");
        return a + b;
    }

    public static void main(String[] args) {
        System.out.println(add(1, 2));        // → 两个 int
        System.out.println(add(1, 2, 3));     // → 三个 int
        System.out.println(add(1.5, 2.5));    // → 两个 double
    }
}

运行结果思路:

  • add(1, 2) → 匹配两个 int
  • add(1, 2, 3) → 匹配三个 int
  • add(1.5, 2.5) → 匹配两个 double

你不用记“该调哪个”,编译器按参数自动选。

1.4 生活类比

点外卖说“来一份套餐”:

  • 套餐(一人份)
  • 套餐(两人份)
  • 套餐(儿童份)

都叫“套餐”,但份量(参数)不同 → 厨房做不同的。这就是重载。

1.5 常见坑

// ❌ 错误:只改返回值,不算重载
public static int get() { return 1; }
public static void get() { }  // 编译失败
// ⚠️ 调用时注意自动匹配
add(1, 2.0);  // 1 会提升成 double,走 add(double, double)

2. 值传递(Java 只有值传递)

2.1 核心结论(先背这个)

Java 方法参数永远是“值传递”:传的是副本。

  • 基本类型:传的是数值的副本
  • 引用类型:传的是地址的副本(不是对象本身再拷一份)

2.2 基本类型:改参数,外面不动

public class PassByValueDemo {

    public static void change(int num) {
        num = 100;  // 只改副本
        System.out.println("方法里 num = " + num);
    }

    public static void main(String[] args) {
        int a = 10;
        change(a);
        System.out.println("方法外 a = " + a);  // 仍是 10
    }
}

图解:

main 里的 a = 10
        ↓ 调用 change(a)
方法里的 num = 10(复印件)
        ↓ num = 100
方法里的 num = 100
方法外的 a  仍然是 10(原件没动)

2.3 引用类型:地址副本 + 对象可改

public class ArrayPassDemo {

    public static void changeFirst(int[] arr) {
        arr[0] = 999;           // 通过副本地址,改的是同一个数组对象
        arr = new int[]{1, 2};  // 只让“方法里的副本”指向新数组,外面不变
    }

    public static void main(String[] args) {
        int[] nums = {10, 20, 30};
        changeFirst(nums);
        System.out.println(nums[0]);  // 999
        System.out.println(nums[1]);  // 20
    }
}

记住两句话:

  1. arr[0] = 999 → 改对象内容 → 外面能看到
  2. arr = new ... → 改的是方法里的地址副本 → 外面看不到

2.4 交换两个数:为什么这样写不行?

public static void swap(int a, int b) {
    int temp = a;
    a = b;
    b = temp;  // 只交换了副本
}

public static void main(String[] args) {
    int x = 1, y = 2;
    swap(x, y);
    System.out.println(x + ", " + y);  // 还是 1, 2
}

正确思路(先用数组练手,后面学对象再写更好):

public static void swap(int[] arr) {
    int temp = arr[0];
    arr[0] = arr[1];
    arr[1] = temp;
}

3. 方法拆分思维(今天最值钱)

3.1 为什么要拆?

不好的写法(全塞进 main):

public static void main(String[] args) {
    // 输入、校验、计算、打印全在一起……又长又乱
}

好的写法:

main        → 只负责流程(点菜)
小方法们    → 各干一件事(切菜、炒菜、装盘)

3.2 拆分原则(超实用)

  1. 一个方法只做一件事(算总分就不要顺便打印)
  2. 名字要能读懂:calcAverage 比 do1 好
  3. 能复用就拆出来(多处用到同一段逻辑)
  4. main 保持短小:看起来像步骤清单

3.3 完整案例:学生成绩小程序

需求:录入 3 门课成绩 → 算总分 → 算平均 → 评等级 → 打印报告。

import java.util.Scanner;

public class ScoreApp {

    public static void main(String[] args) {
        double[] scores = inputScores(3);
        double total = calcTotal(scores);
        double avg = calcAverage(total, scores.length);
        String level = getLevel(avg);
        printReport(total, avg, level);
    }

    // 1. 录入成绩
    public static double[] inputScores(int count) {
        Scanner sc = new Scanner(System.in);
        double[] scores = new double[count];
        for (int i = 0; i < count; i++) {
            System.out.print("请输入第" + (i + 1) + "门课成绩:");
            scores[i] = sc.nextDouble();
        }
        return scores;
    }

    // 2. 算总分
    public static double calcTotal(double[] scores) {
        double sum = 0;
        for (double s : scores) {
            sum += s;
        }
        return sum;
    }

    // 3. 算平均
    public static double calcAverage(double total, int count) {
        return total / count;
    }

    // 4. 评等级(可再配合重载)
    public static String getLevel(double avg) {
        if (avg >= 90) return "优秀";
        if (avg >= 80) return "良好";
        if (avg >= 60) return "及格";
        return "不及格";
    }

    // 5. 打印报告
    public static void printReport(double total, double avg, String level) {
        System.out.println("===== 成绩报告 =====");
        System.out.println("总分:" + total);
        System.out.println("平均:" + avg);
        System.out.println("等级:" + level);
    }
}

对照看:main 几乎像中文步骤——这就是拆分成功的标志。

3.4 同一案例再加“重载”

// 按平均分评等级
public static String getLevel(double avg) { ... }

// 按总分和科目数评等级(参数不同 → 重载)
public static String getLevel(double total, int subjectCount) {
    return getLevel(total / subjectCount);  // 复用上面那个
}

4. 今日必会清单

  •  能说出重载的判定条件(名同,参不同)
  •  知道“只改返回值”不算重载
  •  理解基本类型传参改不了外面的变量
  •  理解数组传参:改元素外面能看到,改引用外面看不到
  •  能把一个“大 main”拆成 3~5 个小方法

5. 课后小练习(建议动手)

练习 1:重载

写一组 max

  • max(int a, int b)
  • max(int a, int b, int c)
  • max(double a, double b)

练习 2:值传递

预测下面输出,再运行验证:

public static void test(int n, int[] arr) {
    n = 50;
    arr[0] = 50;
}
// int x = 1; int[] a = {1, 2};
// test(x, a);  打印 x 和 a[0]

练习 3:拆分

把“打印九九乘法表”拆成

  • printLine(int row):打印一行
  • printTable():打印整张表
  • main 只调用 printTable()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值