Lớp trong TypeScript
Bài viết này giải thích về lớp trong TypeScript.
YouTube Video
Lớp trong TypeScript
Lớp trong TypeScript được dựa trên các lớp ES6 của JavaScript và cung cấp các tính năng bổ sung như chú thích kiểu và bộ điều chỉnh truy cập. Điều này cho phép bạn tận dụng các khái niệm lập trình hướng đối tượng trong khi đảm bảo tính an toàn kiểu rõ ràng và mạnh mẽ hơn.
Dưới đây là các giải thích về cách sử dụng cơ bản và các tính năng của lớp trong TypeScript.
Định nghĩa lớp cơ bản
1class Person {
2 name: string; // Member variable
3 age: number; // Member variable
4
5 // Constructor
6 constructor(name: string, age: number) {
7 this.name = name;
8 this.age = age;
9 }
10
11 // Method
12 greet(): void {
13 console.log(`Hello, my name is ${this.name} and I am ${this.age} years old.`);
14 }
15}
16
17const person = new Person("Alice", 25);
18person.greet(); // Hello, my name is Alice and I am 25 years old.
name
vàage
là các thuộc tính (biến thành viên) của lớp.constructor
là một phương thức được gọi khi tạo instance của một lớp, nhận các đối số và gán giá trị cho các thuộc tính.greet
là một phương thức của lớp, cho biết rằng nó không có giá trị trả về nhờ kiểuvoid
.
Bộ điều chỉnh truy cập
Trong TypeScript, bạn có thể sử dụng các bộ điều chỉnh truy cập (public
, private
, protected
) để kiểm soát quyền truy cập vào thuộc tính và phương thức của lớp.
public
Mặc định, tất cả các thuộc tính và phương thức đều là public
. Điều này có nghĩa là chúng có thể được truy cập từ bên ngoài lớp.
1class Animal {
2 public species: string;
3
4 constructor(species: string) {
5 this.species = species;
6 }
7
8 public makeSound(): void {
9 console.log(`${this.species} makes a sound.`);
10 }
11}
12
13const animal = new Animal("Dog");
14console.log(animal.species); // Dog
15animal.makeSound(); // Dog makes a sound.
- Thuộc tính
species
và phương thứcmakeSound
được khai báo làpublic
nên có thể truy cập từ bên ngoài lớp.
private
Sử dụng bộ điều chỉnh private
sẽ ngăn truy cập vào thuộc tính hoặc phương thức từ bên ngoài lớp.
1class Car {
2 private brand: string;
3
4 constructor(brand: string) {
5 this.brand = brand;
6 }
7
8 public getBrand(): string {
9 return this.brand;
10 }
11}
12
13const car = new Car("Toyota");
14// console.log(car.brand); // Error: 'brand' is private and cannot be accessed.
15console.log(car.getBrand()); // Toyota
- Thuộc tính
brand
được khai báo làprivate
, vì vậy không thể truy cập từ bên ngoài lớp. - Đóng gói dữ liệu có thể được thực hiện bằng cách ẩn các thuộc tính với từ khóa
private
.
protected
Bộ điều chỉnh protected
giới hạn quyền truy cập từ bên ngoài lớp nhưng cho phép trong các lớp con (lớp dẫn xuất).
1class Vehicle {
2 protected model: string;
3
4 constructor(model: string) {
5 this.model = model;
6 }
7}
8
9class Truck extends Vehicle {
10 public getModel(): string {
11 return this.model;
12 }
13}
14
15const truck = new Truck("Ford F-150");
16console.log(truck.getModel()); // Ford F-150
17
18// console.log(truck.model);
19// Error: Property 'model' is protected and only accessible within class 'Vehicle' and its subclasses.
- Thuộc tính
model
được khai báo làprotected
, vì vậy không thể truy cập từ bên ngoài lớp, nhưng có thể được truy cập từ các lớp con.
Getters và Setters
Trong TypeScript, bạn có thể định nghĩa getters và setters bằng cách sử dụng từ khóa get
và set
để lấy và thiết lập giá trị thuộc tính.
1class Employee {
2 private _salary: number;
3
4 constructor(salary: number) {
5 this._salary = salary;
6 }
7
8 // Getter
9 get salary(): number {
10 return this._salary;
11 }
12
13 // Setter
14 set salary(newSalary: number) {
15 if (newSalary > 0) {
16 this._salary = newSalary;
17 } else {
18 console.log("Salary must be positive.");
19 }
20 }
21}
22
23const employee = new Employee(50000);
24console.log(employee.salary); // 50000
25employee.salary = 60000;
26console.log(employee.salary); // 60000
27employee.salary = -100; // Salary must be positive.
- Trong ví dụ này, getter và setter được sử dụng cho thuộc tính
salary
để kiểm soát việc truy cập và cập nhật từ bên ngoài. Setter sẽ kiểm tra giá trị để ngăn các giá trị âm và hiển thị thông báo cảnh báo nếu người dùng nhập giá trị không hợp lệ.
Kế thừa
Trong TypeScript, các lớp có thể được kế thừa. Bằng cách sử dụng từ khóa extends
, bạn có thể kế thừa các chức năng từ lớp cha.
1class Animal {
2 constructor(public name: string) {}
3
4 public move(): void {
5 console.log(`${this.name} is moving.`);
6 }
7}
8
9class Bird extends Animal {
10 public fly(): void {
11 console.log(`${this.name} is flying.`);
12 }
13}
14
15const bird = new Bird("Sparrow");
16bird.move(); // Sparrow is moving.
17bird.fly(); // Sparrow is flying.
- Trong ví dụ này, lớp
Bird
kế thừa từ lớpAnimal
, do đó có thể sử dụng phương thứcmove
của lớpAnimal
. Hơn nữa, lớp này định nghĩa phương thứcfly
riêng, bổ sung tính năng mới đồng thời kế thừa các đặc điểm từ lớp cha.
Lớp trừu tượng
Lớp trừu tượng (abstract
) không thể được khởi tạo trực tiếp và được sử dụng làm mẫu để cung cấp các triển khai cụ thể trong các lớp con.
1abstract class Shape {
2 abstract getArea(): number;
3
4 public describe(): void {
5 console.log("This is a shape.");
6 }
7}
8
9class Circle extends Shape {
10 constructor(private radius: number) {
11 super();
12 }
13
14 public getArea(): number {
15 return Math.PI * this.radius * this.radius;
16 }
17}
18
19const circle = new Circle(5);
20console.log(circle.getArea()); // 78.53981633974483
21circle.describe(); // This is a shape.
- Trong ví dụ này,
Shape
được định nghĩa là một lớp trừu tượng vàgetArea
là một phương thức trừu tượng phải được các lớp con triển khai. LớpCircle
kế thừa lớp trừu tượng này và tự triển khai phương thứcgetArea
để tính diện tích hình tròn. Ngoài ra, các phương thức cụ thể nhưdescribe
được kế thừa như một chức năng chung và có thể sử dụng trực tiếp.
Quan hệ với Interface
Các lớp có thể triển khai interface, đảm bảo rằng chúng có các thuộc tính và phương thức cụ thể.
1interface Flyable {
2 fly(): void;
3}
4
5class Airplane implements Flyable {
6 public fly(): void {
7 console.log("The airplane is flying.");
8 }
9}
10
11const airplane: Flyable = new Airplane();
12airplane.fly(); // The airplane is flying.
- Trong ví dụ này, interface
Flyable
định nghĩa đặc tả cho phương thứcfly
, và lớpAirplane
triển khai interface này bằng cách cung cấp định nghĩa cụ thể cho phương thứcfly
. Nhờ đó, bất kỳ đối tượng nào có thể được coi là kiểuFlyable
đều đảm bảo có phương thứcfly
.
Thành viên tĩnh
Khi bạn định nghĩa thành viên tĩnh trong một lớp, các phương thức và thuộc tính đó sẽ liên kết trực tiếp với lớp mà không phụ thuộc vào đối tượng. Các thành viên tĩnh có thể được gọi mà không cần khởi tạo đối tượng từ lớp.
1class MathUtils {
2 static PI: number = 3.14;
3
4 static add(a: number, b: number): number {
5 return a + b;
6 }
7}
8
9console.log(MathUtils.add(10, 20)); // 30
10console.log(MathUtils.PI); // 3.14
- Bạn định nghĩa các phương thức tĩnh bằng từ khóa
static
. - Trong ví dụ này, lớp
MathUtils
định nghĩa một phương thức tĩnhadd
và một thuộc tính tĩnhPI
. - Các thành viên tĩnh không thuộc về các đối tượng, mà có thể được gọi trực tiếp từ chính lớp đó.
Tóm tắt
Các lớp TypeScript thêm các tính năng như an toàn kiểu dữ liệu, các trình sửa đổi quyền truy cập và các lớp trừu tượng vào chức năng lớp của JavaScript. Điều này cho phép lập trình hướng đối tượng mạnh mẽ hơn và an toàn hơn.
Bạn có thể làm theo bài viết trên bằng cách sử dụng Visual Studio Code trên kênh YouTube của chúng tôi. Vui lòng ghé thăm kênh YouTube.