Constructor & destructor
Tìm hiểu về hai phương thức đặc biệt của class
Tìm hiểu về hai phương thức đặc biệt của class
Constructor (hàm tạo) và destructor (hàm hủy) là 2 phương thức đặc biệt của class.
Constructor giúp tạo ra object từ class, và ngược lại, destructor dùng để phá hủy object và giải phóng bộ nhớ.
Trong Delphi, constructor có tên cố định là Create, destructor có tên là Destroy.
Mọi class trong delphi đều có 2 method Create và Destroy, do kế thừa từ lớp tổ tiên là TObject.
Về chức năng, constructor làm nhiệm vụ chuẩn bị cho class sẵn sàng được sử dụng. Ví dụ, trong class của bạn có một số class con như sau.
type
TClass = class
AField: TSubClass;
end;
thì khi TClass được tạo ra bằng Create, trường ÀField cũng phải được tạo ra luôn (vì AField là trường đối tượng chứ không phải kiểu dữ liệu thông thường). Hàm constructor còn có một chức năng nữa là khởi tạo nhanh cho object, sẽ được nói đến sau.
Ngược lại, destructor sẽ xóa các đối tượng con của class khi class bị hủy.
Đoạn code sau miêu tả một lớp học TClass, với trường TenLop và một field TStringList lưu danh sách học sinh. Chúng ta sẽ sử dụng constructor và destructor vì trường HS cần được khởi tạo khi TClass tạo.
Lưu ý: Constructor và destructor nên được để public.
Vì constructor và destructor đều là những method, nên khai báo và triển khai giống như các method khác.
type
TClass = class
TenLop: string;
HS: TStringList;
public
constructor Create;
destructor Destroy;
end;
constructor TClass.Create;
begin
inherited Create;
HS := TStringList.Create;
end;
destructor TClass.Destroy;
begin
HS.Free;
inherited Destroy;
end;
Chú ý: Trong code trên mình có sử dụng từ khóa inherited. Đại loại nó dùng cho lớp con để gọi hàm ngược lên lớp cha. Nên khi viết inherited Create có nghĩa là gọi hàm Create của lớp cha. (từ khóa inherited này sẽ được bàn đến trong bài kế thừa)
Phải gọi hàm Create của lớp cha trước để đối tượng được tạo, sau đó mới thực hiện lệnh tiếp theo. Ngược lại, với destructor thì gọi inherited Destroy cuối cùng để đảm bảo rằng đối tượng bị hủy.
Nhìn vào code trên, bạn có thể thấy constructor để tạo object HS khi TClass được tạo, sau đó trong destructor phá hủy nó đi để tránh lãng phí bộ nhớ.
Đây là một kĩ thuật lợi dụng constructor để khởi tạo nhanh giá trị cho các field của object. Ví dụ, bạn có class THocSinh với các thông tin (field) như sau
type
THocSinh = class
HoTen: string;
Tuoi: Byte;
Lop: string;
Truong: string;
end;
và bạn khởi tạo một object HS1.
var
HS1, HS2: THocSinh;
Bạn muốn khởi tạo HS1 và HS2 với một số thông tin như: tên Nguyễn Văn A, 12 tuổi, lớp 6A, trường tiểu học ABC chẳng hạn. Cách thông thường bạn sẽ làm như sau
HS1 := THocSinh.Create;
HS2 := THocSinh.Create;
try
HS1.HoTen := 'Nguyen Van A';
HS1.Tuoi := 12;
HS1.Lop := '6A';
HS1.Truong := 'Tieu hoc ABC';
HS2.HoTen := 'Nguyen Van A';
HS2.Tuoi := 12;
HS2.Lop := '6A';
HS2.Truong := 'Tieu hoc ABC';
...
finally
HS1.Free;
HS2.Free;
end;
Cách này khá dài dòng và rắc rối, nếu bạn có 10 học sinh, điều này sẽ khó khăn hơn rất nhiều.
Thay vào đó, bạn có thể lợi dụng constructor với các tham số cần thiết, và gọi luôn một lần. Mình sẽ viết lại toàn bộ code trên theo cách mới này.
type
THocSinh = class
HoTen: string;
Tuoi: Byte;
Lop: string;
Truong: string;
public
constructor Create(HoTen: string; Tuoi: Byte; Lop, Truong: string);
end;
constructor THocSinh.Create(HoTen: string; Tuoi: Byte; Lop, Truong: string);
begin
Self.HoTen := HoTen;
Self.Tuoi := Tuoi;
Self.Lop := Lop;
Self.Truong := Truong;
end;
var
HS1, HS2: THocSinh;
begin
HS1 := THocSinh.Create('Nguyen Van A', 12, '6A', 'Tieu hoc ABC');
HS2 := THocSinh.Create('Le Thi B', 12, '6B', 'Tieu hoc ABC');
try
...
finally
HS1.Free;
HS2.Free;
end;
end.
Như trên, các thông tin được khởi tạo ngay trong hàm Create, nên sẽ làm code ngắn hơn, viết code đỡ vất vả hơn.
Code từ đây sẽ dài hơn, bạn có thể hiểu được không ?