Như chúng ta đã biết, C# là ngôn ngữ lập trình hướng đối tượng, chính vì thế việc tạo ra các đối tượng (objects) trong một chương trình viết bằng C# là điều không thể thiếu. Vậy làm thế nào để tạo ra các đối tượng (objects) mong muốn khi cần sử dụng chúng trong chương trình của mình? Khi đó chúng ta cần xây dựng class trong chương trình là có thể tạo ra đối tượng.
1. Class là gì? Gồm những thành phần nào?
– Một lớp/class là một khái niệm mô tả cho những thực thể/đối tượng có chung tính chất/thuộc tính và hành vi/phương thức. Lớp định nghĩa những thuộc tính và hành vi được dùng cho những đối tượng của lớp đó. Do đó có thể nói lớp là một khuôn mẫu cho các đối tượng.
– Vậy đối tượng là gì?
Đối tượng là một đại diện, hay có thể nói là một sản phẩm của một class. Tất cả các đối tượng đều có chung những thuộc tính và hành vi mà class định nghĩa. Cách tạo đối tượng giống như cách tạo một biến có kiểu dữ liệu là class.
– Để dễ hình dung, chúng ta có minh họa sau:
– Class là kiểu dữ liệu do người dùng tự định nghĩa và class là kiểu tham chiếu. Access modifier mặc định cho kiểu class nếu không chỉ định là internal, còn của thuộc tính là private.
– Một class thì bao gồm thuộc tính (là các danh từ) và phương thức (là các động từ). Được khai báo bắt đầu bằng từ khóa class như sau:
<access modifier> class tên_lớp { // Khai báo các thuộc tính <access modifier> <kiểu_dữ_liệu> tên_biến_1; <access modifier> <kiểu_dữ_liệu> tên_biến_2; ... <access modifier> <kiểu_dữ_liệu> tên_biến_n; // Khai báo các phương thức <access modifier> <kiểu_trả_về> tên_phương_thức_1(danh_sách_tham_số) { // định nghĩa phương thức } <access modifier> <kiểu_trả_về> tên_phương_thức_2(danh_sách_tham_số) { // định nghĩa phương thức } ... <access modifier> <kiểu_trả_về> tên_phương_thức_n(danh_sách_tham_số) { // định nghĩa phương thức } }
Trong đó:
- access modifier : chỉ định phạm vi truy cập, có thể là public, protected, internal, private.
- class : từ khóa dùng để khai báo một lớp.
- tên_lớp, tên_biến, tên_phương_thức : tuân thủ theo quy tắc đặt tên trong lập trình.
- kiểu_trả_về : có thể là kiểu dữ liệu có sẵn của .Net, hoặc là kiểu dữ liệu do người dùng tự định nghĩa.
– Ví dụ: chúng ta khai báo một class Xe Hơi như bên dưới:
{
// Khai báo các thuộc tính
public string TenXe;
public string MauSac;
public int NamSanXuat;
// Khai báo các phương thức
//・Phương thức có kiểu trả về
public bool Chay()
{
Console.WriteLine( "Chạy…" );
return true;
}
//・Phương thức không có kiểu trả về
public void TangToc(int VanToc)
{
Console.WriteLine( "Tăng tốc… {0} km/h", VanToc );
}
}
[/code]
2. Cách tạo đối tượng và truy xuất các thành phần của lớp
#1. Khởi tạo đối tượng
– Bạn sử dụng toán tử new với cú pháp như sau:
<TênLớp> <tên_đối_tượng> = new TênLớp()
– Ví dụ:
[/code]
#2. Truy xuất các thành phần của lớp
– Bạn sử dụng toán tử dấu chấm(.) với cú pháp như sau:
// Truy cập thuộc tính <tên_đối_tượng>.<tên_thuộc_tính>; // Truy cập phương thức <tên_đối_tượng>.<tên_phương_thức>( <danh_sách_tham_số_nếu_có> );
– Ví dụ:
toyota.TenXe = "Toyota";
// Truy xuất (gọi) phương thức
toyota.TangToc( 80 );
[/code]
– Ở đây mình chỉ tập trung minh họa cách khai báo đối tượng và sử dụng đối tượng để truy xuất các thành phần của lớp như thế nào. Chúng ta xét ví dụ đơn giản: tạo đối tượng xe toyota từ lớp Xe Hơi, sau đó truy xuất vào thuộc tính Tên xe và phương thức Tăng tốc của lớp Xe hơi:
namespace MinhHoangBlog
{
class Program
{
static void Main(string[] args)
{
// Khởi tạo đối tượng [toyota] từ lớp [XeHoi]
XeHoi toyota = new XeHoi();
// Truy xuất và gán giá trị cho thuộc tính
toyota.TenXe = "Toyota";
Console.WriteLine( "Tên xe: " + toyota.TenXe );
// Truy xuất (gọi) phương thức
toyota.TangToc( 80 );
Console.ReadKey();
}
}
public class XeHoi
{
// Khai báo các thuộc tính
public string TenXe;
public string MauSac;
public int NamSanXuat;
// Khai báo các phương thức
//・Phương thức có kiểu trả về
public bool Chay()
{
Console.WriteLine( "Chạy…" );
return true;
}
//・Phương thức không có kiểu trả về
public void TangToc(int VanToc)
{
Console.WriteLine("Tăng tốc… {0} km/h", VanToc);
}
}
}
[/code]
3. Hàm dựng/Hàm khởi tạo Constructor
– Phương thức khởi tạo constructor là một phương thức đặc biệt và là phương thức đầu tiên được gọi và chỉ gọi một lần khi khởi tạo đối tượng, nó nhằm thiết lập các tham số đầu tiên cho đối tượng.
Nếu class không khai báo constructor, trình biên dịch tự động tạo một constructor mặc định không tham số. Khi đó các biến thành viên sẽ được khởi tạo theo các giá trị mặc định ( kiểu int là 0, bool là false, kiểu tham chiếu là null,… ).
– Constructor có một số đặc điểm như sau:
- Có tên trùng với tên lớp.
- Không có kiểu trả về.
- Được tự động gọi khi một đối tượng thuộc lớp được khởi tạo.
- Có thể có một hoặc nhiều constructor bên trong một lớp.
- Nếu lớp không khai báo bất kỳ phương thức khởi tạo nào thì trình biên dịch tự động tạo một hàm dựng mặc định không tham số và không có nội dung gì.
– Có 2 loại constructor:
- Constructor không tham số: là phương thức khởi tạo mặc định, nếu lập trình viên không khai báo thì trình biên dịch sẽ tự tạo ngầm định. Phương thức này không có tham số. Thường dùng để khởi tạo các giá trị mặc định cho các thuộc tính bên trong class khi khởi tạo đối tượng.
- Constructor có tham số: là phương thức khởi tạo có tham số truyền vào. Và khi khởi tạo đối tượng sử dụng bằng phương thức này, chúng ta cần truyền đầy đủ các tham số. Thường dùng để khởi tạo các giá trị cho các thuộc thuộc tính bên trong class khi khởi tạo đối tượng (các giá trị này do người khởi tạo đối tượng truyền vào).
– Cú pháp khai báo constructor:
// Khai báo constructor không tham số <access modifier> tên_lớp { // định nghĩa phương thức } // Khai báo constructor có tham số <access modifier> tên_lớp(danh_sách_tham_số) { // định nghĩa phương thức }
– Minh họa cách sử dụng phương thức khởi tạo constructor:
■ Class XeHoi
{
// Khai báo các thuộc tính
public string TenXe;
public int NamSanXuat;
// Constructor không tham số
public XeHoi()
{
// Khởi tạo giá trị cho thuộc tính có thể có hoặc không
// TenXe = "Toyota";
// NamSanXuat = 2017;
}
// Constructor có tham số
public XeHoi(string inTenXe, int inNamSanXuat)
{
TenXe = inTenXe;
NamSanXuat = inNamSanXuat;
}
}
[/code]
■ Hàm main() khởi tạo đối tượng bằng constructor không tham số
{
static void Main(string[] args)
{
// Tạo đối tượng bằng constructor không tham số
XeHoi car = new XeHoi();
// Xem giá trị của thuộc tính
string TenXe = car.TenXe; // TenXe = null
int NamSanXuat = car.NamSanXuat; // NamSanXuat = 0
Console.ReadKey();
}
}
[/code]
Như các bạn thấy, nếu chúng ta tạo đối tượng bằng constructor không tham số mà không khởi tạo giá trị mặc định cho các biến thành viên(TenXe, NamSanXuat), thì các biến này sẽ được khởi tạo bằng giá trị mặc định của kiểu dữ liệu: string là null, int là 0.
■ Hàm main() khởi tạo đối tượng bằng constructor có tham số
{
static void Main(string[] args)
{
// Tạo đối tượng bằng constructor không tham số
XeHoi car = new XeHoi("Audi", 2010);
// Xem giá trị của thuộc tính
string TenXe = car.TenXe; // tenXe = Audi
int NamSanXuat = car.NamSanXuat; // namSanXuat = 2010
Console.ReadKey();
}
}
[/code]
Còn khi chúng ta tạo đối tượng bằng constructor có tham số thì giá trị của các biến thành viên sẽ chính là các giá trị được truyền vào tương ứng cho constructor.
Một số điểm lưu ý:
- Trường hợp trong một lớp có nhiều constructor thì tùy vào cách bạn gọi constructor là có tham số hay không tham số, và số lượng tham số truyền vào mà chỉ có một constructor tương ứng được gọi để tạo đối tượng.
- Các tham số của constructor có tham số sẽ mang các giá trị tương ứng cho các thuộc tính bên trong lớp vì thế nên:
- Khai báo chúng có cùng kiểu dữ liệu với thuộc tính tương ứng.
- Đặt tên chúng gợi nhớ đến thuộc tính tương ứng để tránh nhầm lẫn. Và khi muốn truy xuất vào thuộc tính nào thì cũng dễ hiểu, dễ nhận biết khi đọc code.
Xem thêm:
– Hàm dựng (constructor) và tính kế thừa trong C#.
– Hàm hủy Destructor trong C#.
[…] Một số kiểu tham chiếu là: object, string, class, delegate, interface, array, dynamic, kiểu do lập trình viên tự định nghĩa (thực ra […]
Cảm ơn nhiều!
[…] Extension method và instance method: khi trong class đang thao tác có một instance method cùng tên với extension method thì khi gọi: […]