Constructor là một trong những khái niệm cơ bản mà bạn nào học về lập trình đều cần nắm vững. Hãy cùng Rikkei Academy dành 5 phút để tìm hiểu tất tần tật về Constructor trong Java qua bài viết này nhé!
Constructor trong Java là gì?
Constructor trong Java là một phương thức đặc biệt được sử dụng để khởi tạo đối tượng của một lớp. Nó có chức năng tạo ra một đối tượng mới của lớp đó và khởi tạo các thuộc tính của đối tượng đó. Constructor được gọi tự động khi một đối tượng mới được tạo bằng từ khóa “new”.
Ngoài ra, constructor trong Java được sử dụng để khởi tạo các thuộc tính của đối tượng và các giá trị khác cần thiết cho đối tượng. Nó cũng được sử dụng để thiết lập các giá trị mặc định cho các thuộc tính của đối tượng và khởi tạo các đối tượng khác mà đối tượng hiện tại cần để thực hiện các chức năng của nó.
Các kiểu constructor trong Java
Trong Java, có ba loại constructor (hàm khởi tạo) như sau:
Default Constructor (Hàm khởi tạo mặc định)
Default constructor là constructor không có tham số, được Java tự động tạo ra nếu bạn không định nghĩa bất kỳ constructor nào trong lớp. Default constructor sẽ khởi tạo các trường dữ liệu của lớp với giá trị mặc định (số nguyên là 0, số thực là 0.0, boolean là false, đối tượng là null).
Cú pháp của default constructor:
public ClassName() {
// Các câu lệnh khởi tạo } |
Ví dụ:
public class Animal {
private String name; private int age; // Default constructor public Animal() { this.name = “”; this.age = 0; } } |
No-args Constructor (Hàm khởi tạo không có tham số)
No-args constructor là constructor không có tham số (no arguments), cũng giống như default constructor. Tuy nhiên, nếu bạn định nghĩa một no-args constructor, Java sẽ không tự động tạo ra một default constructor. No-args constructor cho phép bạn kiểm soát cách các trường dữ liệu được khởi tạo. Ví dụ như thiết lập kết nối với cơ sở dữ liệu hoặc thiết lập một số giá trị mặc định cho thuộc tính của đối tượng.
Ngoài ra, Phần mã thân (body) của Default Constructor luôn trống, tức là không có câu lệnh nào được thực hiện trong constructor này. Trong khi đó, với No-args Constructor, mã thân có thể chứa bất kỳ câu lệnh nào, tương tự như các constructor khác.
Cú pháp của no-args constructor:
public ClassName() {
// Các câu lệnh khởi tạo } |
Ví dụ:
public class Person {
private String name; private int age; // No-args constructor public Person() { name = “Unknown”; age = 0; } |
Lớp Car có một no-args constructor được định nghĩa để khởi tạo trường dữ liệu brand, model và year với các giá trị mặc định do bạn chỉ định.
Parameterized Constructor (Hàm khởi tạo có tham số)
Là constructor có tham số được định nghĩa để khởi tạo đối tượng với các giá trị được truyền vào. Được sử dụng khi cần truyền vào các giá trị cụ thể để khởi tạo đối tượng. Thông thường, các tham số sẽ tương ứng với các thuộc tính của đối tượng để khởi tạo giá trị cho chúng.
Cú pháp Parameterized Constructor:
public ClassName(Type1 param1, Type2 param2, …) {
// Các câu lệnh khởi tạo } |
Ví dụ:
public class Person {
private String name; private int age; public Person(String name, int age) { this.name = name; this.age = age; } |
Constructor Overloading trong Java là gì?
Constructor overloading trong Java là kỹ thuật cho phép chúng ta tạo nhiều hơn một constructor trong cùng một lớp, nhưng mỗi constructor có thể có các tham số khác nhau. Khi tạo đối tượng của lớp đó, chúng ta có thể sử dụng bất kỳ constructor nào phù hợp với nhu cầu của chương trình.
Khi sử dụng constructor overloading, ta có thể khởi tạo đối tượng với nhiều cách khác nhau, tùy thuộc vào các tham số được truyền vào. Giả sử bạn đang viết một ứng dụng quản lý học sinh. Bạn muốn tạo ra một hàm khởi tạo cho lớp này để khởi tạo đối tượng học sinh với các thông tin cơ bản như tên, tuổi, giới tính và địa chỉ. Tuy nhiên, bạn cũng muốn tạo ra một hàm khởi tạo khác để khởi tạo đối tượng học sinh với tất cả các thông tin, bao gồm cả điểm trung bình.
Ví dụ:
public class Student { String name;
int age; String gender; String address; double gpa; // Constructor với thông tin cơ bản public Student(String name, int age, String gender, String address) { this.name = name; this.age = age; this.gender = gender; this.address = address; } // Constructor với tất cả thông tin public Student(String name, int age, String gender, String address, double gpa) { this.name = name; this.age = age; this.gender = gender; this.address = address; this.gpa = gpa; } // Getter and setter methods for all attributes // … } |
Ở ví dụ, ta tạo một lớp Rectangle với hai thuộc tính là length và width. Chúng ta cũng tạo ba constructor khác nhau với số lượng tham số khác nhau.
Trong phương thức main(), chúng ta sử dụng các constructor khác nhau để tạo ba đối tượng Rectangle với các thuộc tính khác nhau. Chúng ta in ra chi tiết của tất cả các hình chữ nhật. Kết quả sẽ in ra:
Rectangle 1: 0 x 0
Rectangle 2: 10 x 0 Rectangle 3: 10 x 20 |
Copy Constructor trong Java là gì?
Copy constructor trong Java là một constructor đặc biệt được sử dụng để tạo ra một đối tượng mới là bản sao của một đối tượng đã tồn tại. Copy constructor thường được định nghĩa bằng cách sử dụng từ khóa “this” để trỏ đến đối tượng mới được tạo ra và sử dụng từ khóa “other” để trỏ đến đối tượng cần sao chép.
Để sao chép các giá trị của một đối tượng sang một đối tượng khác trong Java, ngoài copy constructor, ta có thể sử dụng hai phương pháp sau: gán giá trị của một đối tượng cho đối tượng khác và sử dụng phương thức clone() của lớp Object. Tuy nhiên, copy constructor thường được ưu tiên sử dụng trong các trường hợp sau:
- Khi ta muốn tạo ra một đối tượng mới với các giá trị thuộc tính giống với một đối tượng đã tồn tại.
- Khi ta muốn thực hiện các thao tác trên một đối tượng nhưng không muốn ảnh hưởng đến đối tượng ban đầu.
- Khi muốn thực hiện phép toán trên các đối tượng.
public class Car {
private String model; private int year; // Constructor public Car(String model, int year) { this.model = model; this.year = year; } // Copy constructor public Car(Car otherCar) { this.model = otherCar.model; this.year = otherCar.year; } // Getters and setters public String getModel() { return model; } public void setModel(String model) { this.model = model; } public int getYear() { return year; } public void setYear(int year) { this.year = year; } } // Main class public class Main { public static void main(String[] args) { // Tạo một đối tượng Car với model là “BMW” và năm sản xuất là 2021 Car car1 = new Car(“BMW”, 2021); // Sử dụng copy constructor để tạo một đối tượng Car mới từ car1 Car car2 = new Car(car1); // Thay đổi model và năm sản xuất của car2 car2.setModel(“Mercedes”); car2.setYear(2022); // In ra model và năm sản xuất của cả hai xe System.out.println(“Car 1: ” + car1.getModel() + “, ” + car1.getYear()); System.out.println(“Car 2: ” + car2.getModel() + “, ” + car2.getYear()); } } |
Kết quả:
Car 1: BMW, 2021
Car 2: Mercedes, 2022 |
Constructor chaining trong Java là gì?
Trong Java, một lớp có thể có nhiều hơn một constructor. Khi một đối tượng được khởi tạo, một trong các constructor sẽ được gọi để khởi tạo đối tượng đó. Constructor chaining là cơ chế cho phép gọi một constructor khác trong cùng lớp hoặc lớp cha của nó, thay vì viết lại các đoạn mã khởi tạo lại thuộc tính của lớp. Điều này cho phép tránh việc lặp lại mã trong các constructor khác nhau và tăng tính tái sử dụng của mã. Constructor chaining gồm 2 loại:
Gọi constructor trong cùng lớp
Trong trường hợp này, từ khóa “this” được sử dụng để gọi constructor khác trong cùng lớp. Constructor gọi đến sẽ được thực thi trước constructor gọi nó. Lưu ý: Từ khóa “this” phải là câu lệnh đầu tiên trong constructor.
Trong ví dụ sau, Constructor đầu tiên không có tham số và gọi constructor thứ hai bằng từ khóa “this”. Constructor thứ hai lại gọi constructor thứ ba và constructor thứ ba lại gọi constructor thứ tư để khởi tạo các thuộc tính của lớp. Khi một đối tượng Car được khởi tạo, constructor đầu tiên sẽ được gọi và đến constructor thứ tư để khởi tạo các thuộc tính của lớp Car.
Ví dụ:
public class Car {
private String brand; private String model; private int year; public Car() { this(“Unknown”, “Unknown”, 0); } public Car(String brand) { this(brand, “Unknown”, 0); } public Car(String brand, String model) { this(brand, model, 0); } public Car(String brand, String model, int year) { this.brand = brand; this.model = model; this.year = year; } |
Gọi constructor của lớp cha
Trong trường hợp này, từ khóa “super” được sử dụng để gọi constructor của lớp cha. Constructor của lớp cha sẽ được thực thi trước constructor của lớp con. Lưu ý: từ khoá super phải là câu lệnh đầu tiên trong constructor.
Trong ví dụ, Constructor của lớp con Dog gọi constructor của lớp cha Animal bằng từ khóa “super”. Constructor của lớp cha sẽ được thực thi trước constructor của lớp con để khởi tạo thuộc tính “name” của lớp cha, sau đó constructor của lớp con sẽ được thực thi để khởi tạo thuộc tính “breed” của lớp con.
Ví dụ:
public class Animal {
private String name; private int age; public Animal(String name) { this.name = name; } } public class Dog extends Animal { private String breed; public Dog(String name, String breed) { super(name); this.breed = breed; } |
Kế thừa Constructor trong Java
khi một lớp kế thừa từ một lớp cha, ta có thể sử dụng từ khóa “super()” để gọi constructor của lớp cha. Lưu ý rằng, lệnh “super()” phải được đặt ở dòng đầu tiên trong phương thức khởi tạo của lớp con để đảm bảo rằng constructor của lớp cha được gọi trước khi constructor của lớp con được thực thi. Nếu không có lệnh “super()” trong hàm khởi tạo của lớp con, Java sẽ tự động gọi hàm khởi tạo mặc định (no-args constructor) của lớp cha.
Ví dụ:
public class Student extends Person {
public Student(String name, int age, String major) { super(name, age); // gọi constructor của lớp cha Person this.major = major; // khởi tạo thuộc tính major của lớp con Student } } |
Trong ví dụ trên, constructor của lớp cha “Person” được gọi thông qua lệnh “super(name, age)”, sau đó thuộc tính “major” của lớp con “Student” được khởi tạo.
Khác nhau giữa Method và Constructor trong Java
Hàm khởi tạo (constructor) trong Java trông giống với một phương thức (method), nhưng có một số điểm khác biệt chính như sau:
- Tên: tên hàm khởi tạo phải trùng với tên lớp (class name), trong khi đó tên phương thức có thể đặt tùy ý.
- Kiểu trả về: Hàm khởi tạo không có kiểu trả về (void, int, String, …) và không trả về giá trị gì, trong khi đó phương thức có thể có kiểu trả về và trả về giá trị tương ứng.
- Được gọi: Hàm khởi tạo được gọi tự động khi một đối tượng mới được tạo ra bằng từ khóa new, trong khi đó phương thức phải được gọi bằng cách sử dụng tên phương thức và các tham số tương ứng.
- Overloading: Một lớp có thể có nhiều constructor khác nhau với cùng tên nhưng khác nhau về số lượng và kiểu tham số, trong khi đó một lớp cũng có thể có nhiều phương thức khác nhau với cùng tên nhưng khác nhau về số lượng và kiểu tham số.
- Mục đích sử dụng: Hàm khởi tạo được sử dụng để khởi tạo đối tượng và thiết lập các giá trị ban đầu cho các thuộc tính của đối tượng, trong khi đó phương thức thực hiện các thao tác xử lý và trả về giá trị tùy ý.
Lưu ý rằng cách duy nhất để gọi hàm khởi tạo lớp cha từ trong hàm khởi tạo lớp con là lệnh super() chứ không gọi đích danh tên hàm như Animal() hay Object().
Một số câu hỏi thường gặp về Constructor trong Java
- Tại sao chúng ta cần constructor trong Java?
Constructor giúp chúng ta khởi tạo đối tượng với các giá trị ban đầu. Nó cũng giúp đảm bảo rằng các thuộc tính của đối tượng được khởi tạo đầy đủ trước khi đối tượng được sử dụng.
- Constructor có thể có giá trị trả về không?
Không. Constructor không có giá trị trả về và không cần khai báo kiểu trả về.
- Constructor có thể được gọi từ một phương thức khác không?
Có, constructor có thể được gọi từ một phương thức khác trong cùng lớp.
- Constructor có thể được kế thừa không?
Constructor không thể được kế thừa nhưng lớp con có thể gọi constructor của lớp cha bằng từ khóa “super”.
- Có thể có nhiều constructor trong một lớp không?
Có, một lớp có thể có nhiều constructor với các đối số khác nhau hoặc không có đối số.
- Constructor có thể bị ghi đè không?
Constructor không thể bị ghi đè. Tuy nhiên, lớp con có thể có constructor của riêng nó và gọi constructor của lớp cha bằng từ khóa “super”.
- Constructor có thể là private không?
Có, constructor có thể là private để ngăn chặn việc tạo đối tượng từ bên ngoài lớp. Chúng ta có thể sử dụng phương thức tĩnh hoặc phương thức factory để tạo đối tượng.
Kết luận
Như vậy, Rikkei Academy đã cung cấp tổng quan thông tin về Constructor trong Java. Hy vọng bài viết này đã giúp bạn có cái nhìn sâu hơn về Hàm khởi tạo. Nếu bạn muốn tìm hiểu thêm nhiều thông tin về ngôn ngữ lập trình Java, truy cập chuyên mục Tin tức để theo dõi các bài viết mới nhất nhé!
Nếu bạn muốn học lập trình nhưng chưa biết bắt đầu từ đâu, tham khảo ngay khóa học lập trình Java tại Rikkei Academy nhé! Đăng ký để nhận tư vấn miễn phí ngay hôm nay!