JavaScript - Đa hình

Xin chào các pháp sư JavaScript tương lai! Hôm nay, chúng ta sẽ bắt đầu một hành trình đầy thú vị vào thế giới đa hình trong JavaScript. Đừng lo lắng nếu từ này听起来 đáng sợ - đến cuối bài học này, bạn sẽ sử dụng đa hình như một chuyên gia!

JavaScript - Polymorphism

Đa hình trong JavaScript

Hãy bắt đầu từ cơ bản. Đa hình là một từ tiếng Hy Lạp có nghĩa là "nhiều hình thức." Trong lập trình, nó đề cập đến khả năng của các đối tượng có thể lấy nhiều hình thức hoặc hành vi khác nhau. Hãy tưởng tượng như một con báo thay đổi màu sắc để thích nghi với các môi trường khác nhau.

Trong JavaScript, đa hình cho phép chúng ta sử dụng một giao diện duy nhất để đại diện cho các loại đối tượng khác nhau. Nó giống như việc có một remote điều khiển universal có thể điều khiển nhiều thiết bị khác nhau - TV, đầu DVD và hệ thống âm thanh - tất cả chỉ với cùng một nút bấm.

Dưới đây là một ví dụ đơn giản để minh họa khái niệm này:

function makeSound(animal) {
console.log(animal.sound());
}

let dog = {
sound: function() {
return "Woof!";
}
};

let cat = {
sound: function() {
return "Meow!";
}
};

makeSound(dog); // Output: Woof!
makeSound(cat); // Output: Meow!

Trong ví dụ này, chúng ta có một hàm makeSound có thể làm việc với các đối tượng động vật khác nhau. Cả dogcat đều có phương thức sound, nhưng chúng tạo ra các đầu ra khác nhau. Đây là đa hình trong hành động!

Thừa kế phương thức

Một trong những khía cạnh quan trọng của đa hình là việc thừa kế phương thức. Điều này xảy ra khi một lớp con cung cấp một thực thi cụ thể cho một phương thức đã được định nghĩa trong lớp cha của nó.

Hãy xem một ví dụ:

class Animal {
makeSound() {
return "The animal makes a sound";
}
}

class Dog extends Animal {
makeSound() {
return "The dog barks";
}
}

class Cat extends Animal {
makeSound() {
return "The cat meows";
}
}

let animal = new Animal();
let dog = new Dog();
let cat = new Cat();

console.log(animal.makeSound()); // Output: The animal makes a sound
console.log(dog.makeSound());    // Output: The dog barks
console.log(cat.makeSound());    // Output: The cat meows

Ở đây, chúng ta có một lớp Animal với phương thức makeSound. Các lớp DogCat kế thừa Animal và ghi đè phương thức makeSound bằng cách cung cấp các thực thi riêng của chúng. Điều này cho phép mỗi động vật có âm thanh riêng biệt trong khi vẫn là một phần của gia đình Animal.

Ví dụ

Hãy đi sâu hơn với nhiều ví dụ hơn để thực sự hiểu rõ đa hình trong JavaScript.

Ví dụ 1: Máy tính hình học

Hãy tưởng tượng chúng ta đang xây dựng một máy tính hình học. Chúng ta muốn tính diện tích của các hình khác nhau bằng cùng một tên phương thức.

class Shape {
calculateArea() {
return 0;
}
}

class Circle extends Shape {
constructor(radius) {
super();
this.radius = radius;
}

calculateArea() {
return Math.PI * this.radius * this.radius;
}
}

class Rectangle extends Shape {
constructor(width, height) {
super();
this.width = width;
this.height = height;
}

calculateArea() {
return this.width * this.height;
}
}

function printArea(shape) {
console.log("The area is: " + shape.calculateArea());
}

let circle = new Circle(5);
let rectangle = new Rectangle(4, 6);

printArea(circle);    // Output: The area is: 78.53981633974483
printArea(rectangle); // Output: The area is: 24

Trong ví dụ này, chúng ta có một lớp cơ bản Shape và hai lớp dẫn xuất, CircleRectangle. Mỗi lớp thực hiện phương thức calculateArea của riêng mình. Hàm printArea có thể làm việc với bất kỳ đối tượng hình học nào, minh họa đa hình.

Ví dụ 2: Hệ thống lương thưởng nhân viên

Hãy tạo một hệ thống lương thưởng đơn giản cho nhân viên để minh họa thêm đa hình:

class Employee {
constructor(name, salary) {
this.name = name;
this.salary = salary;
}

calculateBonus() {
return this.salary * 0.1;
}
}

class Manager extends Employee {
calculateBonus() {
return this.salary * 0.2;
}
}

class Developer extends Employee {
calculateBonus() {
return this.salary * 0.15;
}
}

function printBonus(employee) {
console.log(`${employee.name}'s bonus is: $${employee.calculateBonus()}`);
}

let john = new Employee("John", 50000);
let jane = new Manager("Jane", 70000);
let bob = new Developer("Bob", 60000);

printBonus(john); // Output: John's bonus is: $5000
printBonus(jane); // Output: Jane's bonus is: $14000
printBonus(bob);  // Output: Bob's bonus is: $9000

Trong ví dụ này, chúng ta có các loại nhân viên khác nhau với các quy tắc tính thưởng khác nhau. Hàm printBonus có thể làm việc với bất kỳ đối tượng nhân viên nào, thể hiện đa hình.

Lợi ích của việc sử dụng Đa hình trong JavaScript

Bây giờ chúng ta đã thấy đa hình trong hành động, hãy nói về lý do tại sao nó lại tuyệt vời:

  1. Tính tái sử dụng mã: Đa hình cho phép chúng ta viết mã通用 và tái sử dụng. Các hàm printAreaprintBonus của chúng ta có thể làm việc với bất kỳ đối tượng hình học hoặc nhân viên nào, tương ứng.

  2. Tính linh hoạt: Nó dễ dàng thêm các loại đối tượng mới mà không cần thay đổi mã hiện có. Chúng ta có thể thêm một lớp Triangle vào máy tính hình học mà không cần sửa đổi hàm printArea.

  3. Tính dễ bảo trì: Đa hình có thể dẫn đến mã sạch sẽ, tổ chức tốt hơn và dễ bảo trì hơn.

  4. Tính trừu tượng: Nó cho phép chúng ta làm việc với các đối tượng ở cấp độ trừu tượng cao hơn, tập trung vào những gì các đối tượng làm而不是它们如何做.

Dưới đây là bảng tóm tắt các phương thức chính chúng ta đã sử dụng trong các ví dụ:

Phương thức Mô tả
calculateArea() Tính diện tích của một hình
calculateBonus() Tính thưởng cho một nhân viên
makeSound() Trả về âm thanh mà một động vật tạo ra
sound() Trả về âm thanh mà một động vật tạo ra (trong ví dụ đối tượng văn bản)

Nhớ nhé, cácpadawan trẻ, đa hình giống như một cây kéo đa năng trong bộ công cụ lập trình của bạn. Nó linh hoạt, mạnh mẽ và có thể làm cho mã của bạn trở nên tinh tế và hiệu quả hơn. Hãy tiếp tục luyện tập, và sớm bạn sẽ thành thạo JavaScript với đa hình!

Credits: Image by storyset