Ở các phần trước, chúng ta đã dùng biến, object, function và class ở mức cơ bản. Bài này đi sâu hơn một bước: tổ chức dữ liệu và hành vi bằng lập trình hướng đối tượng (Object-Oriented Programming – OOP). Mục tiêu là đọc hiểu và tự viết được những class nhỏ thường gặp trong project automation.
OOP là gì?
OOP là cách tổ chức chương trình xoay quanh các object. Mỗi object thường chứa hai nhóm thông tin:
Ví dụ với 1 đối tượng Nguyễn Văn A thì sẽ có:
- Thuộc tính: tên, tuổi, địa chỉ, giới tính…
- Hành vi: ăn, ngủ, chơi…
Ở ví dụ trên, Nguyễn Văn A là 1 object của class Human
| Khái niệm | Hiểu đơn giản | Ví dụ |
|---|---|---|
| Class | Bản thiết kế để tạo ra các đối tượng | Human |
| Object | Một đối tượng được tạo từ bản thiết kế | Nguyễn Văn A |
| Property | Dữ liệu của object | name, age, address |
| Method | Hành vi của object | eat(), sleep(), wakeUp() |
Class và object
Một class mô tả object sẽ có dữ liệu gì và làm được gì. Khi dùng từ khóa new, TypeScript tạo ra một object cụ thể từ class đó.
class TestCase {
name: string;
priority: string;
constructor(name: string, priority: string) {
this.name = name; //gán param name vào property name ở bên trên của class
this.priority = priority; //tương tự
}
run(): void {
console.log("Running: " + this.name + " [" + this.priority + "]");
}
}
const loginTest = new TestCase("Login successfully", "High");
loginTest.run();class TestCase:
def __init__(self, name: str, priority: str) -> None:
self.name = name
self.priority = priority
def run(self) -> None:
print(f"Running: {self.name} [{self.priority}]")
login_test = TestCase("Login successfully", "High")
login_test.run()Trong ví dụ trên, TestCase là class; loginTest là object. Hai property name và priority lưu dữ liệu, còn run() là method mô tả hành vi.
Constructor dùng để khởi tạo object
constructor chạy tự động mỗi khi chúng ta gọi new TestCase(...). Nó nhận dữ liệu ban đầu và gán dữ liệu đó cho object.
TypeScript có cú pháp rút gọn: thêm access modifier ngay trước parameter trong constructor. Trình biên dịch sẽ tự tạo property và gán giá trị, giúp giảm code lặp. Ví dụ dưới đây bạn có thể thấy không cần khai báo properties cho class này, khai báo trực tiếp luôn trong constructor:
class TestUser {
constructor(
public email: string,
public role: string,
public isActive: boolean = true,
) {}
}
const student = new TestUser("student@elitest.vn", "student");
console.log(student.email);
console.log(student.isActive);class TestUser:
def __init__(
self,
email: str,
role: str,
is_active: bool = True,
) -> None:
self.email = email
self.role = role
self.is_active = is_active
student = TestUser("student@elitest.vn", "student")
print(student.email)
print(student.is_active)this là object hiện tại
Bên trong class, this trỏ tới object đang gọi method. Vì vậy cùng một method nhưng có thể thao tác với dữ liệu khác nhau của từng object.
class Person {
constructor(public name: string) {}
introduce(): void {
console.log("Mình là " + this.name);
}
}
const linh = new Person("Linh");
const an = new Person("An");
linh.introduce(); // this là object linh
an.introduce(); // this là object anclass Person:
def __init__(self, name: str) -> None:
self.name = name
def introduce(self) -> None:
print("Mình là " + self.name)
linh = Person("Linh")
an = Person("An")
linh.introduce() # self là object linh
an.introduce() # self là object anMột class có thể tạo nhiều object
Class chỉ cần định nghĩa một lần nhưng có thể tạo bao nhiêu object tùy ý. Mỗi object giữ state riêng; cập nhật object này không tự động làm thay đổi object khác.
class PiggyBank {
balance: number = 0;
constructor(public owner: string) {}
addMoney(amount: number): void {
this.balance += amount;
}
}
const linhPiggyBank = new PiggyBank("Linh");
const anPiggyBank = new PiggyBank("An");
linhPiggyBank.addMoney(100_000);
anPiggyBank.addMoney(50_000);
console.log(linhPiggyBank.balance); // 100000
console.log(anPiggyBank.balance); // 50000class PiggyBank:
def __init__(self, owner: str) -> None:
self.owner = owner
self.balance = 0
def add_money(self, amount: int) -> None:
self.balance += amount
linh_piggy_bank = PiggyBank("Linh")
an_piggy_bank = PiggyBank("An")
linh_piggy_bank.add_money(100_000)
an_piggy_bank.add_money(50_000)
print(linh_piggy_bank.balance) # 100000
print(an_piggy_bank.balance) # 50000Class quản lý một nhóm object
OOP không chỉ dùng để mô tả từng object riêng lẻ. Một class có thể quản lý danh sách object khác, ví dụ một test suite chứa nhiều test case.
class TestCase {
constructor(
public name: string,
public status: "Passed" | "Failed",
) {}
}
class TestSuite {
private testCases: TestCase[] = [];
add(testCase: TestCase): void {
this.testCases.push(testCase);
}
countFailed(): number {
return this.testCases.filter(
(testCase) => testCase.status === "Failed",
).length;
}
}
const smokeSuite = new TestSuite();
smokeSuite.add(new TestCase("Login", "Passed"));
smokeSuite.add(new TestCase("Create article", "Failed"));
console.log(smokeSuite.countFailed()); // 1class TestCase:
def __init__(self, name: str, status: str) -> None:
self.name = name
self.status = status
class TestSuite:
def __init__(self) -> None:
self._test_cases: list[TestCase] = []
def add(self, test_case: TestCase) -> None:
self._test_cases.append(test_case)
def count_failed(self) -> int:
return len([
test_case
for test_case in self._test_cases
if test_case.status == "Failed"
])
smoke_suite = TestSuite()
smoke_suite.add(TestCase("Login", "Passed"))
smoke_suite.add(TestCase("Create article", "Failed"))
print(smoke_suite.count_failed()) # 1Bài tập nhỏ
- Tạo class
Studentcóname,emailvàisActive. - Dùng constructor để nhận
namevàemail;isActivemặc định làtrue. - Thêm method
deactivate()để chuyểnisActivethànhfalse. - Tạo hai object và kiểm tra state của chúng độc lập với nhau.
Tóm tắt
- Class là bản thiết kế; object là đối tượng cụ thể được tạo từ class.
- Property lưu dữ liệu; method mô tả hành vi.
- Constructor khởi tạo dữ liệu khi tạo object.
thistrỏ tới object đang thực thi method.- Một class có thể tạo nhiều object, mỗi object là độc lập với nhau




