在 Java 中重载构造函数
![在 Java 中重载构造函数](/img/Java/feature-image---java-overload-constructor.webp)
本教程介绍如何在 Java 中重载构造函数。我们还列出了一些示例代码,你可以遵循这些示例代码以更好地理解该主题。
构造函数是一种为类对象分配内存并为该对象初始化类属性的方法。如果没有为类创建构造函数,则 Java 提供一个默认构造函数。
例如,在下面的类中没有定义构造函数。不过,我们可以创建该类的对象,同时将属性初始化为其默认值(在本例中为 null)。
Java 中的默认构造函数
class Student {
String name;
Double gpa;
}
public class Main {
public static void main(String[] args) {
Student s = new Student();
System.out.println(s.name + "\t" + s.gpa);
}
}
输出:
null null
构造函数重载的概念类似于方法重载,这意味着我们对单个类有多个构造函数。构造函数重载是为了以不同的方式初始化类的成员变量。
我们可以根据需要创建任意数量的重载构造函数。唯一的条件是重载的构造函数应该在它们采用的参数数量和类型上有所不同。
例如,参考下面显示的具有两个属性的 Student
类:student name
和 GPA
。为该类定义了一个构造函数,它接受一个字符串名称和一个双 GPA
作为参数,并为新对象初始化相应的属性。
Java 中的参数化构造函数
class Student {
String name;
Double gpa;
Student(String s, Double g) {
name = s;
gpa = g;
}
}
public class Main {
public static void main(String[] args) {
Student s = new Student("Justin", 9.75);
System.out.println(s.name + "\t" + s.gpa);
}
}
输出:
Justin 9.75
没有构造函数重载的代码
考虑在创建新对象时仅将学生姓名传递给构造函数的场景;在这种情况下,GPA
应自动设置为 null
。如果我们不重载构造函数而只传递名称,则会出现以下编译错误。
class Student {
String name;
Double gpa;
Student(String s, Double g) {
name = s;
gpa = g;
}
}
public class Main {
public static void main(String[] args) {
Student s = new Student("Justin");
System.out.println(s.name + "\t" + s.gpa);
}
}
输出:
Exception in thread "main" java.lang.Error: Unresolved compilation problem:
The constructor Student(String) is undefined
at ConstructorOverloading.main(ConstructorOverloading.java:18)
Java 中的构造函数重载
我们可以创建一个仅以学生姓名作为参数的重载构造函数来解决上述情况。调用此构造函数时,我们会将 GPA
设置为 null
。
class Student {
String name;
Double gpa;
Student(String s, Double g) {
name = s;
this.gpa = g;
}
Student(String s) {
name = s;
gpa = null; // Setting GPA to null
}
}
public class Main {
public static void main(String[] args) {
Student s1 = new Student("Justin");
Student s2 = new Student("Jessica", 9.23);
System.out.println(s1.name + "\t" + s1.gpa);
System.out.println(s2.name + "\t" + s2.gpa);
}
}
输出:
Justin null
Jessica 9.23
考虑另一种情况,其中创建了 Student
对象,但名称和 GPA
均未提及。我们可以创建另一个不带参数的重载构造函数(默认构造函数)并将 name
和 GPA
属性设置为 null
。
请记住,Java 仅在没有为类创建其他构造函数时才提供默认构造函数。但是对于我们的类,构造函数已经存在,因此我们需要创建一个默认构造函数。
class Student {
String name;
Double gpa;
Student(String s, Double g) {
name = s;
gpa = g;
}
Student(String s) {
name = s;
gpa = null;
}
Student() {
name = null;
gpa = null;
}
}
public class Main {
public static void main(String[] args) {
Student s1 = new Student();
Student s2 = new Student("Justin");
Student s3 = new Student("Jessica", 9.23);
System.out.println(s1.name + "\t" + s1.gpa);
System.out.println(s2.name + "\t" + s2.gpa);
System.out.println(s3.name + "\t" + s3.gpa);
}
}
输出:
null null
Justin null
Jessica 9.23
构造函数重载最佳实践
重载构造函数时没有固定的指导方针。但是,我们可以遵循一些推荐的最佳实践,以避免混淆并减少错误的范围。
- 应该使用
this
关键字来引用类的成员变量。它避免了混淆并使我们的代码更具可读性。 - 我们还可以将更直观的参数名称传递给构造函数。例如,如果构造函数初始化 name 字段,则构造函数签名可以是
Student(String name)
而不是Student(String s)
。使用this
关键字,我们可以区分称为name
的参数和也称为name
的类属性。
让我们继续 Student
类的示例,并在构造函数中使用 this
关键字。
class Student {
String name;
Double gpa;
Student(String name, Double gpa) // passing more intuitive parameter names
{
this.name = name; // using this keyword to avoid confusion
this.gpa = gpa;
}
Student(String name) {
this.name = name;
this.gpa = null;
Student()
this.name = null;
this.gpa = null;
}
}
- 一个类只有一个
单一主构造函数
也是一个很好的做法,所有剩余的构造函数都应该调用这个主构造函数来初始化属性。 - 我们可以使用
this()
函数从另一个构造函数调用构造函数。我们传递给this()
的属性的数量和类型将决定调用哪个构造函数。 - 它会减少代码冗余,我们只需要为单个构造函数编写逻辑。
- 在
Student
类中,我们需要三个重载的构造函数。主要构造函数将是参数化的构造函数,它以name
和GPA
作为参数。另外两个重载的构造函数将简单地调用主构造函数并将参数的值作为null
传递。
class Student {
String name;
Double gpa;
Student(String name, Double gpa) // Primary Constructor that sets the attribute values
{
this.name = name;
this.gpa = gpa;
}
Student(String name) {
this(name, null); // Calling the primary constructor with GPA as null
}
Student() {
this(null, null); // Calling the primary constructor with both parameters as null
}
}
重载构造函数
重载构造函数是为了以不同的方式初始化类的属性。重载的构造函数应该在参数数量或传递给它们的参数的数据类型方面有所不同。
每个构造函数的签名应该与其他构造函数不同。我们应该使用 this
关键字来引用类属性和其他构造函数,因为它使我们的代码更少冗余且更易于理解。