Trong bài viết này, chúng ta sẽ khám phá constructor trong Java, một khái niệm quan trọng trong lập trình hướng đối tượng. Chúng ta sẽ tìm hiểu về định nghĩa, cách tạo, sự khác biệt giữa constructor mặc định và constructor do người dùng định nghĩa, cũng như khái niệm overloaded constructor.
Mục Lục
Định nghĩa Constructor
Trong Java, constructor là một phương thức đặc biệt được sử dụng để khởi tạo và trả về một đối tượng của lớp mà nó thuộc về. Constructor có tên trùng với tên lớp và không có kiểu trả về.
Ví dụ:
public class Student {
int age;
String name;
public Student() {
// Constructor của lớp Student
}
}
Trong ví dụ trên, chúng ta đã định nghĩa một constructor cho đối tượng Student
. Lưu ý rằng nó không có kiểu trả về và tên của nó trùng với tên lớp Student
.
Khi một đối tượng được tạo bằng cách gọi constructor của nó với toán tử new
, constructor của lớp cha sẽ được gọi và tất cả các biến instance (instance variable) sẽ được khởi tạo với giá trị mặc định của chúng. Ví dụ, khi khởi tạo đối tượng Student
bằng cách gọi:
Student student = new Student();
thì giá trị của biến age
trong đối tượng Student
sẽ có giá trị mặc định của kiểu int
, là 0.
Constructor trong Java là gì?
Constructor mặc định
Nếu trong một lớp, chúng ta không định nghĩa bất kỳ constructor nào, Java sẽ tự động thêm một constructor mặc định vào lớp đó.
Ví dụ, nếu chúng ta định nghĩa lớp Student
như sau:
public class Student {
int age;
String name;
}
Lúc này, chúng ta vẫn có thể khởi tạo đối tượng Student
bằng cách:
Student student = new Student();
Mặc dù chúng ta không định nghĩa bất kỳ constructor nào trong lớp Student
, chúng ta vẫn có thể khởi tạo đối tượng này.
Constructor mặc định không chứa bất kỳ tham số nào và khi được gọi để khởi tạo đối tượng, nó cũng gọi constructor của lớp cha và khởi tạo giá trị mặc định cho các biến instance.
Tuy nhiên, nếu chúng ta đã định nghĩa một constructor cho lớp:
public class Student {
int age;
String name;
public Student(String name) {
this.name = name;
}
}
thì Java sẽ không tự động thêm constructor mặc định nữa. Khi đó, nếu chúng ta cố gắng khởi tạo đối tượng bằng constructor mặc định, trình biên dịch sẽ báo lỗi:
Student student = new Student(); // Lỗi compile
Lỗi khi cố gắng gọi constructor mặc định sau khi đã định nghĩa constructor khác
Định nghĩa Constructor
Chúng ta có thể định nghĩa constructor cho một lớp bất kỳ. Khi đó, tất cả các thuộc tính của đối tượng, bao gồm các phương thức và các biến instance, có thể được gọi tùy theo định nghĩa của chúng ta.
Ví dụ:
public class Student {
int age;
String name;
public Student(String name, int age) {
this.name = name;
this.age = age;
}
}
Chúng ta có thể sử dụng bốn access modifier (public, private, protected, default) để định nghĩa cho một constructor, và do đó chúng ta có thể giới hạn phạm vi truy cập của đối tượng từ các đối tượng khác.
Điều gì sẽ xảy ra nếu chúng ta định nghĩa một constructor với một kiểu giá trị trả về? Khi đó, Java sẽ coi nó như là một phương thức bình thường chứ không phải là một constructor.
Ví dụ:
public class Student {
int age;
String name;
public void Student(String name) { // Đây là một phương thức, không phải constructor
this.name = name;
}
}
Đối tượng Student
lúc này chỉ có một constructor mặc định do Java thêm vào. Nếu chúng ta khởi tạo đối tượng Student
với một tham số name
, trình biên dịch sẽ báo lỗi.
Overloaded Constructor
Overloaded constructor là khi chúng ta định nghĩa nhiều constructor cho một lớp và mỗi constructor sẽ có các tham số khác nhau, cả về số lượng và kiểu dữ liệu của tham số.
Ví dụ:
public class Student {
int age;
String name;
public Student() {
this.name = "Unknown";
this.age = 0;
}
public Student(String name) {
this.name = name;
this.age = 0;
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
}
Nguyên tắc để định nghĩa overloaded constructor là:
- Các constructor phải được định nghĩa sử dụng các tham số khác nhau, cả về số lượng và kiểu dữ liệu của tham số.
- Các constructor không được định nghĩa chỉ khác nhau ở access modifier.
Trong trường hợp một lớp có nhiều constructor và chúng ta muốn gọi constructor này từ constructor khác, chúng ta phải sử dụng từ khóa this
như sau:
public class Student {
int age;
String name;
public Student() {
this("Unknown", 0); // Gọi constructor Student(String name, int age)
}
public Student(String name) {
this(name, 0); // Gọi constructor Student(String name, int age)
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
}
Câu lệnh this()
để gọi constructor khác phải nằm ở dòng đầu tiên của constructor. Nếu nó nằm sau một câu lệnh bất kỳ, code sẽ báo lỗi compile:
public class Student {
int age;
String name;
public Student() {
System.out.println("Constructor mặc định");
this("Unknown", 0); // Lỗi compile: this() phải là lệnh đầu tiên
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
}
Lỗi khi câu lệnh this() không nằm ở dòng đầu tiên
Qua bài viết này, hy vọng bạn đã nắm vững kiến thức về constructor trong Java, bao gồm định nghĩa, cách sử dụng constructor mặc định và constructor do người dùng định nghĩa, cũng như khái niệm overloaded constructor.