CodeGym /Các khóa học /C# SELF /Lớp và đối tượng: tạo, constructor và khởi tạo

Lớp và đối tượng: tạo, constructor và khởi tạo

C# SELF
Mức độ, Bài học
Có sẵn

1. Tạo đối tượng

Cuối cùng cũng đến phần tạo đối tượng rồi. Bạn đã từng gặp cái này trước đây, chỉ là giờ mình sẽ phân tích kỹ hơn thôi. Thực ra tạo đối tượng dễ lắm.

Để tạo đối tượng, bạn dùng toán tử new. Thường thì bạn tạo một instance (đối tượng) mới của class và lưu nó vào biến cùng kiểu.

Lop ten = new Lop(thamSo);
Cú pháp tạo đối tượng

Ở đây Lop — kiểu của đối tượng, ten — tên biến (thường viết thường, ví dụ cat), còn bên phải = — là tạo đối tượng mới của class đó.

Ví dụ:

Mã Ghi chú
object o = new object();
Tạo đối tượng kiểu object
Cat pet = new Cat();
Tạo đối tượng kiểu Cat
var reader = new StreamReader("file.txt");
Tạo đối tượng StreamReader với tham số

Rất nhiều dev đặt tên biến giống tên class, chỉ khác là viết thường. Người mới học nhìn code kiểu này dễ bị rối:

Mã
Student student = new Student();
Car car = new Car();
PersonInfo personInfo = new PersonInfo();

Thực ra code này không có gì ghê gớm đâu — đây là code bình thường, tạo biến và khởi tạo nó bằng đối tượng cùng kiểu.

Bên trái — khai báo biến, bên phải — tạo đối tượng mới trong bộ nhớ bằng new. Xong!

2. Constructor

Chắc bạn cũng hay thấy khi tạo đối tượng thì truyền vào một số tham số. Có đối tượng thì truyền tham số, có cái thì không. Vậy cơ chế truyền tham số này hoạt động thế nào?

Cũng đơn giản thôi: mỗi class có một (hoặc nhiều) phương thức đặc biệt xử lý tham số khi tạo đối tượng. Mấy phương thức này gọi là constructor. Một phương thức thì gọi là constructor.

Nhận biết constructor với phương thức thường cũng dễ. Constructor có hai đặc điểm:

  • tên constructor giống tên class (và viết hoa chữ cái đầu)
  • constructor không có kiểu trả về (ngay cả void cũng không viết).

Nhìn chung nó sẽ như này:


modifier Lop(thamSo)
{
   code constructor
}
Cú pháp constructor

Ví dụ khai báo constructor:

public class Point
{
    public int X;
    public int Y;

    public Point(int x, int y) // Constructor
    {
        X = x;
        Y = y;
    }
}

Cách dùng:

Point p = new Point(5, 10); // Gọi constructor

Khi tạo đối tượng bằng new Point(5, 10) sẽ gọi constructor với hai tham số, dùng để khởi tạo trường X và Y.

Đôi khi tham số của constructor trùng tên với trường — cho tiện. Trường hợp này giải quyết bằng từ khóa this:

public Point(int x, int y)
{
    this.x = x; // this.x — trường của đối tượng, x — tham số constructor
    this.y = y;
}

3. Gọi constructor

Khi bạn viết new Lop(thamSo), thì C#:

  • tạo đối tượng mới trong bộ nhớ,
  • gọi constructor phù hợp, truyền tham số vào.

Ví dụ với class mèo:

public class Cat
{
    public string Name;
    public int Age;

    public Cat(string name, int age)
    {
        Name = name;
        Age = age;
    }
}

Cách dùng:

Cat cat = new Cat("Vaska", 2); // Được: gọi constructor với hai tham số
Cat cat2 = new Cat("Vaska");   // Không được: không có constructor này — lỗi biên dịch
Cat cat3 = new Cat();           // Không được: không có constructor không tham số — lỗi biên dịch

Nếu class chỉ có constructor có tham số, bạn bắt buộc phải truyền giá trị cho nó khi tạo đối tượng.

4. Nhiều constructor

Nhưng nếu muốn, bạn có thể thêm nhiều constructor vào class. Không giới hạn số lượng constructor hay tham số. Khi tạo đối tượng, compiler sẽ tự chọn constructor phù hợp với tham số bạn truyền.

Ví dụ:

public class Cat
{
    public const int KHONG_BIET = -1;
    public string Name;
    public int Age;

    public Cat(string name, int age)
    {
        Name = name;
        Age = age;
    }

    public Cat(string name)
    {
        Name = name;
        Age = KHONG_BIET; // Giá trị "mặc định" cho tuổi không biết
    }
}

Cách dùng:

Cat cat1 = new Cat("Vaska", 2); // Dùng constructor đầu tiên
Cat cat2 = new Cat("Murka");     // Dùng constructor thứ hai
Cat cat3 = new Cat();            // Lỗi! Không có constructor không tham số

Giả sử tuổi mèo có thể không biết. Trường hợp này mình thêm hằng số đặc biệt — KHONG_BIET và constructor chỉ nhận tên mèo.

Lưu ý là mình vẫn khởi tạo cả hai biến class trong cả hai constructor. Tham số không biết/thừa thì thay bằng hằng số KHONG_BIET.

5. Constructor mặc định

Nếu class của bạn không có constructor nào, compiler sẽ tự động thêm constructor rỗng không tham số:


public ClassName()
{
}
Cú pháp constructor mặc định

Nhưng nếu class đã có ít nhất một constructor tự khai báo — thì constructor rỗng sẽ không được thêm tự động.

Ví dụ 1:

public class Cat
{
    public string Name;
    public int Age;
}

// Được:
Cat cat = new Cat(); // Sẽ gọi constructor mặc định (không tham số)

Ví dụ 2:

public class Cat
{
    public string Name;
    public int Age;

    public Cat(string name) { Name = name; }
}

// Không được:
Cat cat = new Cat(); // Lỗi: không còn constructor không tham số!

6. Khởi tạo biến

Trong C#, biến class có thể khởi tạo ngay khi khai báo, hoặc trong constructor.

Ví dụ:

public class Cat
{
    public string Name;
    public int Age = -1; // Giá trị khởi đầu

    public Cat(string name, int age)
    {
        Name = name;
        Age = age; // Ghi đè giá trị khởi đầu
    }

    public Cat()
    {
        Name = "KhongTen";
        // Age vẫn là -1 (giá trị khởi đầu)
    }
}

Giải thích:

  • Khi tạo bằng new Cat("Vaska", 2) biến Age ban đầu là -1, nhưng constructor sẽ gán lại thành 2.
  • Khi tạo bằng new Cat() — Age vẫn là -1.

7. Thứ tự khởi tạo biến

Dữ liệu của đối tượng mới sẽ được khởi tạo theo thứ tự:

  1. Trường của class đầu tiên nhận giá trị mặc định (0 cho int, null cho kiểu tham chiếu, v.v.).
  2. Sau đó chạy các initializer bạn khai báo khi định nghĩa trường, theo thứ tự xuất hiện trong code.
  3. Và cuối cùng mới chạy code trong constructor.

Biến được khởi tạo trước constructor và theo thứ tự khai báo. Nên chú ý nếu các trường phụ thuộc lẫn nhau.

Ví dụ sai

Trường không static không thể khởi tạo bằng biến không static khác:


public class Solution
{
    public int a = 1; 
    public int b = a;        // không dùng được a
    public int c = a + b;   // không dùng được a và b
}
// Code này sẽ báo lỗi biên dịch!
Lỗi: trường không static không thể tham chiếu lẫn nhau khi khởi tạo

Ví dụ đúng

Với biến static mọi thứ sẽ chạy ngon:

public class Solution
{
    public static int a = 1;          // Gán rõ ràng a = 1
    public static int b = a + 2;      // b = 1 + 2 ⇒ 3
    public static int c = a + b + 3;  // c = 1 + 3 + 3 ⇒ 7

    public Solution()
    {
        Console.WriteLine($"a = {a}, b = {b}, c = {c}");
        // Sẽ in: a = 1, b = 3, c = 7 — đúng như mong đợi
    }
}
Khởi tạo trường static

Ví dụ đúng 2

Với trường static bạn còn có thể viết như này:

public class Solution
{
    public static int a = b + c + 1;    // b và c vẫn là 0
    public static int b = a + c + 2;    // a == 1, c vẫn là 0
    public static int c = a + b + 3;    // a == 1, b == 3
}
Trường static và thứ tự khởi tạo của chúng
2
Nhiệm vụ
C# SELF, mức độ, bài học
Đã khóa
Tạo lớp và đối tượng
Tạo lớp và đối tượng
2
Nhiệm vụ
C# SELF, mức độ, bài học
Đã khóa
Khởi tạo biến và một vài constructor
Khởi tạo biến và một vài constructor
Bình luận
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION