Java: Hàm tạo (Constructor)

Các khóa học qua video:
Python SQL Server PHP C# Lập trình C Java HTML5-CSS3-JavaScript
Học trên YouTube <76K/tháng. Đăng ký Hội viên
Viết nhanh hơn - Học tốt hơn
Giải phóng thời gian, khai phóng năng lực

Tổng quan

Mỗi lớp có thể chứa nhiều thuộc tính trong đó việc khai báo và khởi tạo sẽ trở nên khó khăn để theo dõi nếu chúng được thực hiện bên trong các khối khác nhau. Tương tự như vậy, có thể có những hoạt động khởi đầu khác mà cần được giải quyết trong một ứng dụng, chẳng hạn như mở một tập tin. Java cho phép các đối tượng khởi tạo chính bản thân chúng một cách trực tiếp ngay trong quá trình tạo chúng. Điều này được được thực hiện bằng cách định nghĩa các hàm tạo (constructor) trong lớp.

Mỗi hàm tạo là một phương thức có tên giống với tên của lớp chứa nó. Hàm tạo có nhiệm vụ khởi tạo giá trị cho các thuộc tính hoặc thực hiện các hoạt động khởi tạo chỉ một lần trong khi tạo một đối tượng của lớp. Các hàm tạo sẽ tự động được gọi và thực thi mỗi khi một đối tượng được tạo và gọi đến hàm tạo đó.

Chú ý: Hàm tạo không có kiểu trả về. Điều này là bởi vì kiểu trả về ngầm định của hàm tạo chính là bản thân lớp chứa nó. Bạn cũng có quyền áp dụng hình thức tải chồng phương thức đối với hàm tạo.

Có hai loại hàm tạo chính như sau:

1. Hàm tạo không tham số

Cú pháp khai báo hàm tạo không tham số của một lớp là như sau:

Tên_Lớp() {
  //Các câu lệnh khởi tạo
}

Ví dụ dưới đây định nghĩa một lớp có tên là Animal có một hàm tạo không tham số.

//tạo lớp Animal:
public class Animal {
  //khai báo các thuộc tính:
  int id; //mã nhận diện
  String name; //tên
  float age; //tuổi

  //hàm tạo không tham số
  public Animal() {
    id=1234;
    name="Moon";
    age=1;
  }
}

Trong đoạn mã có định nghĩa một phương thức có tên Animal() và đây chính là hàm tạo. Phương thức này được gọi bởi Máy ảo Java (JVM) để khởi tạo giá trị cho các thuộc tính id, name và age khi đối tượng của lớp được tạo. Hàm tạo này không có bất kỳ tham số nào, vì thế nó được gọi là hàm tạo không tham số.

Lời gọi tới hàm tạo

Hàm tạo được gọi trực tiếp trong quá trình tạo đối tượng. Có nghĩa là mỗi khi toán tử new xuất hiện thì bộ nhớ sẽ được cấp phát cho đối tượng. Hàm tạo, nếu được cung cấp trong lớp thì được gọi bởi JVM để khởi tạo đối tượng. Ví dụ:

class TestAnimal{
  public static void main(String[] args) {
    Animal cat=new Animal(); //gọi tới hàm tạo không tham số
    System.out.println("ID: "+cat.id);
    System.out.println("Name: "+cat.name);
    System.out.println("Age: "+cat.age);
  }
}

Đoạn mã trên tạo một đối tượng có tên cat. Trước tiên đối tượng của lớp Animal sẽ được cấp phát vùng nhớ và sau đó hàm tạo không tham số Animal() được gọi. Vì thế hàm tạo không tham số này (như đã được định nghĩa ở ví dụ phía trên) sẽ khởi tạo giá trị cho các thuộc tính của đối tượng cat là id, name và age.

Kết quả:

ID: 1234
Name: Moon
Age: 1.0

2. Hàm tạo mặc định

Trong trường hợp bạn không định nghĩa hàm tạo nào trong lớp, thì JVM (Java Virtual Machine) sẽ gọi tới hàm tạo mặc định (được trình biên dịch cung cấp) để khởi tạo các đối tượng. Hàm tạo mặc định này không có tham số và nó sẽ khởi tạo giá trị cho các thuộc tính của đối tượng mới các giá trị mặc định ứng với kiểu dữ liệu của từng thuộc tính.

Ví dụ sau định nghĩa lớp có tên NhanVien nhưng không định nghĩa hàm tạo nào.

public class NhanVien {
  // Khai báo các thuộc tính
  String tenNhanVien;
  int tuoiNhanVien;
  double luongNhanVien;
  boolean tinhTrangHonNhan;

  /* Phương thc đ hin th thông tin chi tiết nhân viên */
  void chiTietNhanVien() {
    System.out.println("Chi tiết nhân viên:");
    System.out.println("================");
    System.out.println("Tên: " + tenNhanVien);
    System.out.println("Tui: " + tuoiNhanVien);
    System.out.println("Lương: " + luongNhanVien);
    System.out.println("Tình trng hôn nhân: " + tinhTrangHonNhan);
  }
}

Ví dụ trên khai báo một lớp NhanVien với các thuộc và một phương thức là chiTietNhanVien(). Phương thức này in giá trị của các thuộc tính ra màn hình.

Ví dụ sau đây tạo một lớp có chứa phương thức main() trong đó tạo một đối tượng của lớp NhanVien ở trên và từ đó gọi phương thức chiTietNhanVien() của nó.

public class TestNhanVien {
  public static void main(String[] args) {
    NhanVien objNV = new NhanVien();
    objNV.chiTietNhanVien();
  }
}

Vì lớp NhanVien không có bất kỳ hàm tạo nào được định nghĩa, nên hàm tạo mặc định sẽ được tạo khi thực thi chương trình.

Khi câu lệnh new NhanVien() được thực thi, thì đối tượng được cấp phát vùng nhớ và các thuộc tính được hàm tạo mặc định khởi tạo các giá trị ứng với từng kiểu dữ liệu. Sau đó, phương thức chiTietNhanVien() được thực thi để hiển thị các giá trị của các biến thể hiện của đối tượng objNV.

Bảng dưới đây liệt kê các giá trị mặc định của từng kiểu dữ liệu sẽ được gán cho thuộc tính của lớp nếu lớp đó không có định nghĩa hàm tạo.

Kiểu dữ liệu Giá trị mặc định
byte 0
short 0
int 0
long 0L
float 0.0f
double 0.0
char '\u0000'
boolean false
String null

3. Hàm tạo có tham số

Trong ví dụ bên trên có định nghĩa hàm tạo không tham số cho lớp Animal, trong đó gán giá trị 1234 cho thuộc tính id, "Moon" cho thuộc tính name, và 1 cho thuộc tính age. Và điều này cũng có nghĩa là tất cả các đối tượng của lớp Animal đều sẽ được khởi tạo các giá trị giống nhau cho các thuộc tính khi hàm tạo không tham số được gọi. Điều này không hữu dụng trong nhiều tình huống.

Để khắc phục điều này ta có thể định nghĩa hàm tạo chứa một danh sách các tham số với mục đích khởi tạo giá trị cho các thuộc tính của đối tượng tương ứng. Các giá trị khởi tạo sẽ được truyền cho hàm tạo tương ứng được gọi trong quá trình tạo đối tượng.

Ví dụ sau đây sẽ định nghĩa thêm hàm tạo ba tham số cho lớp Animal.

//tạo lớp Animal:
public class Animal {
  //khai báo các thuộc tính:
  int id; //mã nhận diện
  String name; //tên
  float age; //tuổi

  //hàm tạo không tham số
  public Animal() {
    id=1234;
    name="Moon";
    age=1;
  }
  
  //hàm tạo 3 tham số
  public Animal(int id, String name, float age) {
    this.id = id;
    this.name = name;
    this.age = age;
  }
}

Kết quả:

ID: 1234
Name: Moon
Age: 1.0
ID: 5678
Name: Phú Quốc
Age: 1.5

Ví dụ trên khai báo một hàm tạo ba tham số là Animal(int id, String name, float age). Trong quá trình thực thi, hàm tạo sẽ chấp nhận giá trị của ba tham số và gán chúng cho các thuộc tính id, name, và age của đối tượng được tạo.

Dưới đây là ví dụ hoàn chỉnh, trong đó trong lớp Animal tạo thêm một phương thức có tên showInfo() để hiển thị thông tin các thuộc tính của đối tượng, trong phương thức main() của lớp TestAnimal tạo hai đối tượng có tên cat và dog, trong đó đối tượng cat gọi đến phương thức không tham số, còn đối tượng dog gọi đến phương thức ba tham số.

//tạo lớp Animal:
public class Animal {
  //khai báo các thuộc tính:
  int id; //mã nhận diện
  String name; //tên
  float age; //tuổi

  //hàm tạo không tham số
  public Animal() {
    id = 1234;
    name = "Moon";
    age = 1;
  }

  //hàm tạo 3 tham số
  public Animal(int id, String name, float age) {
    this.id = id;
    this.name = name;
    this.age = age;
  }

  void showInfo() {
    System.out.println("ID: " + id);
    System.out.println("Name: " + name);
    System.out.println("Age: " + age);
  }
}

//tạo lớp TestAnimal:
class TestAnimal {
  public static void main(String[] args) {
    Animal cat = new Animal();
    cat.showInfo();
    Animal dog = new Animal(5678,"Phú Quốc", 1.5f);
    dog.showInfo();
  }
}

Trong quá trình tạo đối tượng dog, những điều sau đây xảy ra theo trình tự:

  1. Việc cấp phát bộ nhớ được thực hiện cho đối tượng mới của lớp (từ khóa new làm điều này).
  2. Các giá trị 5678, "Phú Quốc", và 1.5f được truyền tới hàm tạo ba tham số là Animal(int id, String name, float age) trong đó khởi tạo giá trị cho các thuộc tính của đối tượng là id, name, và age.
  3. Cuối cùng, tham chiếu của đối tượng mới được tạo được trả về và lưu trong biến tham chiếu dog.

Xem thêm:

» Tiếp: Bộ khởi tạo cho đối tượng
« Trước: Truy cập các thuộc tính và phương thức của đối tượng
Các khóa học qua video:
Python SQL Server PHP C# Lập trình C Java HTML5-CSS3-JavaScript
Học trên YouTube <76K/tháng. Đăng ký Hội viên
Viết nhanh hơn - Học tốt hơn
Giải phóng thời gian, khai phóng năng lực
Copied !!!