CodeGym /课程 /JAVA 25 SELF /构造函数重载

构造函数重载

JAVA 25 SELF
第 14 级 , 课程 4
可用

1. 构造函数重载的语法

在实际开发中,很少会所有对象都以同一种方式创建。设想一个类 Person(人)。有时我们只知道姓名就要创建对象;有时——姓名和年龄;而有时——什么都不知道,让一切使用默认值。如果总是强迫类的使用者提供所有参数(即使他并不需要),那就很奇怪了。

构造函数重载是一种给类的使用者“选择权”的方式:他在创建对象时可以指定想要的参数,其他参数使用默认值。这让类更灵活,也更易用。

类比:
在设计部门里造汽车。有人订购基础配置(没有空调,只有方向盘和车轮),有人想要“豪华版”(座椅加热、Wi‑Fi,甚至能自动驾驶)。但不管怎样,汽车仍然是同一个类,只是装配方式不同而已!

重载指的是在同一个类中声明多个构造函数,但它们的参数不同(数量、类型或顺序不同)。它们的名字都与类名相同,并且没有返回类型。

示例:带有重载构造函数的类

public class Person {
    String name;
    int age;

    // 无参构造函数(默认)
    public Person() {
        this.name = "未知";
        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();                // 姓名 = "未知",年龄 = 0
Person p2 = new Person("瓦夏");          // 姓名 = "瓦夏",年龄 = 0
Person p3 = new Person("彼佳", 25);      // 姓名 = "彼佳",年龄 = 25

Java 如何知道用哪个构造函数?

Java 会查看你在 new 之后传入的实参数量和类型。如果你写的是 new Person("瓦夏"),编译器会寻找一个带有一个 String 参数的构造函数。如果你写的是 new Person("彼佳", 25),则需要一个参数为 Stringint 的构造函数。

2. 从一个构造函数调用另一个:this(...)

在重载构造函数时,常会出现部分代码重复的情况。比如你希望所有构造函数都必须设置姓名,而如果年龄未指定就为 0。为了不在每个构造函数中复制相同的逻辑,可以使用关键字 this(...) 从一个构造函数调用另一个。

示例

public class Person {
    String name;
    int age;

    // 双参数构造函数
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    // 单参数构造函数调用另一个构造函数
    public Person(String name) {
        this(name, 0); // 调用 Person(String name, int age)
    }

    // 无参构造函数调用另一个构造函数
    public Person() {
        this("未知", 0);
    }
}
public Person(String name) {
    this(name, 0); // 调用 Person(String, int)
}
通过 this(...) 在构造函数之间相互调用

重要规则:通过 this(...) 调用其他构造函数必须是构造函数中的第一行!

为什么需要这样做?

  • 减少代码重复。
  • 如果你决定更改初始化逻辑(例如修改默认值),只需要在一个地方修改即可。
  • 代码更简洁,更易维护。

3. 实用示例:真实类中的重载

假设我们有一个类 Account —— 银行账户。有时我们只知道所有者的名字,有时想直接指定初始余额,而有时还需要指定货币。

带有重载构造函数的类示例

public class Account {
    String owner;
    double balance;
    String currency;

    // 三参数构造函数
    public Account(String owner, double balance, String currency) {
        this.owner = owner;
        this.balance = balance;
        this.currency = currency;
    }

    // 双参数构造函数(默认货币为 "EUR")
    public Account(String owner, double balance) {
        this(owner, balance, "EUR");
    }

    // 单参数构造函数(余额 = 0,货币 = "EUR")
    public Account(String owner) {
        this(owner, 0.0, "EUR");
    }

    // 无参构造函数(所有者为 "未知",余额 = 0,货币 = "EUR")
    public Account() {
        this("未知", 0.0, "EUR");
    }

    public void printInfo() {
        System.out.println(owner + ": " + balance + " " + currency);
    }
}

用法

public class Main {
    public static void main(String[] args) {
        Account acc1 = new Account("伊万", 1000, "USD");
        Account acc2 = new Account("玛丽亚", 500);
        Account acc3 = new Account("彼得");
        Account acc4 = new Account();

        acc1.printInfo(); // 伊万: 1000.0 USD
        acc2.printInfo(); // 玛丽亚: 500.0 EUR
        acc3.printInfo(); // 彼得: 0.0 EUR
        acc4.printInfo(); // 未知: 0.0 EUR
    }
}

为什么这很方便?

  • 可以按不同的详细程度创建对象。
  • 不必每次都指定所有参数(尤其是在它们经常相同的情况下)。
  • 易于扩展类:如果出现新参数,可以再添加一个构造函数。

4. 构造函数重载中的常见错误

错误 №1:参数类型和顺序混淆。
如果你有两个构造函数 —— Person(String name, int age)Person(int age, String name) —— 编译器可以区分它们,但对类的使用者来说可能非常混乱。最好避免这样的设计。

错误 №2:缺少无参构造函数。
如果你只声明了带参数的构造函数,然后又尝试无参创建对象——会得到编译错误。如果需要无参构造函数,请一定显式添加。

错误 №3:调用其他构造函数不在第一行。
通过 this(...) 的调用必须位于构造函数的第一行。如果在它之前写了其他代码——会导致编译错误。

错误 №4:构造函数调用循环。
如果构造函数直接或通过链式间接调用自身,会因为无限递归而导致编译错误。

错误 №5:字段未初始化。
如果在构造函数(或调用链)中忘记初始化某个字段,对象可能会处于不正确的状态。请确保对象创建后所有字段都有合理的值。

1
任务
JAVA 25 SELF, 第 14 级, 课程 4
已锁定
出版社:书籍仍在制作中或已准备好印刷
出版社:书籍仍在制作中或已准备好印刷
1
任务
JAVA 25 SELF, 第 14 级, 课程 4
已锁定
在网站上注册新用户:不同的场景
在网站上注册新用户:不同的场景
1
任务
JAVA 25 SELF, 第 14 级, 课程 4
已锁定
工厂的智能汽车组装
工厂的智能汽车组装
1
任务
JAVA 25 SELF, 第 14 级, 课程 4
已锁定
多专业学院的学生录取
多专业学院的学生录取
评论
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION