Java 方法多載 (Method Overloading)

方法多載是指同一個類別中,有多個相同名稱但參數不同的方法。

基本概念

public class Calculator {
    // 兩個 int 參數
    public int add(int a, int b) {
        return a + b;
    }
    
    // 三個 int 參數
    public int add(int a, int b, int c) {
        return a + b + c;
    }
    
    // 兩個 double 參數
    public double add(double a, double b) {
        return a + b;
    }
}

多載的規則

方法多載必須符合以下任一條件:

  1. 參數數量不同
  2. 參數型別不同
  3. 參數順序不同
// 參數數量不同
public void method(int a) { }
public void method(int a, int b) { }

// 參數型別不同
public void method(int a) { }
public void method(double a) { }

// 參數順序不同
public void method(int a, String b) { }
public void method(String a, int b) { }

不能只靠回傳型別區分

// 錯誤!回傳型別不同不構成多載
public int getValue() { return 1; }
public double getValue() { return 1.0; }  // 編譯錯誤

實際應用

println() 方法

Java 的 System.out.println() 就是多載的例子:

System.out.println(123);        // int
System.out.println(3.14);       // double
System.out.println("Hello");    // String
System.out.println(true);       // boolean

建構子多載

public class Person {
    private String name;
    private int age;
    
    // 無參數建構子
    public Person() {
        this.name = "Unknown";
        this.age = 0;
    }
    
    // 只有名稱
    public Person(String name) {
        this.name = name;
        this.age = 0;
    }
    
    // 完整參數
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
}

// 使用
Person p1 = new Person();
Person p2 = new Person("Alice");
Person p3 = new Person("Bob", 25);

工具方法

public class StringUtils {
    // 重複字串
    public static String repeat(String s, int times) {
        return s.repeat(times);
    }
    
    // 重複字元
    public static String repeat(char c, int times) {
        return String.valueOf(c).repeat(times);
    }
    
    // 填充字串
    public static String pad(String s, int length) {
        return pad(s, length, ' ');  // 預設空白
    }
    
    public static String pad(String s, int length, char padChar) {
        if (s.length() >= length) return s;
        return String.valueOf(padChar).repeat(length - s.length()) + s;
    }
}

自動型別轉換

Java 會自動進行型別提升來匹配方法:

public class Example {
    public void print(int n) {
        System.out.println("int: " + n);
    }
    
    public void print(double n) {
        System.out.println("double: " + n);
    }
}

Example e = new Example();
e.print(10);      // int: 10
e.print(10.5);    // double: 10.5
e.print((byte)5); // int: 5(byte 自動轉 int)

型別轉換優先順序

byte → short → int → long → float → double
              ↑
             char

方法多載 vs 方法覆寫

特性多載 (Overloading)覆寫 (Overriding)
發生位置同一類別父子類別之間
方法名稱相同相同
參數必須不同必須相同
回傳型別可以不同相同或子型別
決定時機編譯時期執行時期

可變參數的多載

public class Example {
    public void method(int... nums) {
        System.out.println("varargs");
    }
    
    public void method(int a) {
        System.out.println("single int");
    }
    
    public void method(int a, int b) {
        System.out.println("two ints");
    }
}

Example e = new Example();
e.method(1);        // single int(優先匹配具體參數)
e.method(1, 2);     // two ints
e.method(1, 2, 3);  // varargs
e.method();         // varargs

最佳實踐

  1. 相關功能:多載的方法應該執行相關的功能
  2. 避免歧義:不要建立容易混淆的多載
  3. 使用可變參數:考慮用可變參數取代多個多載
// 不好:太多多載
public void process(int a) { }
public void process(int a, int b) { }
public void process(int a, int b, int c) { }
public void process(int a, int b, int c, int d) { }

// 較好:使用可變參數
public void process(int... values) { }