Trong lập trình hướng đối tượng, các khái niệm về tính đóng gói, tính kế thừa, tính đa hình và tính trừu tượng là những khái niệm cơ bản và quan trọng.
Lập trình hướng đối tượng vận hành với 4 tính:
Tính đóng gói đề cập đến việc ẩn thông tin bên trong một đối tượng và chỉ cho phép truy cập thông qua các phương thức công khai. Điều này giúp bảo vệ dữ liệu và đảm bảo tính toàn vẹn của đối tượng. Trong JavaScript, chúng ta có thể sử dụng class để thực hiện tính đóng gói. Dưới đây là một ví dụ:
class BankAccount {
constructor(accountNumber, balance) {
this.accountNumber = accountNumber;
this.balance = balance;
}
deposit(amount) {
this.balance += amount;
}
withdraw(amount) {
if (amount <= this.balance) {
this.balance -= amount;
} else {
console.log("Insufficient funds.");
}
}
getBalance() {
return this.balance;
}
}
const myAccount = new BankAccount("123456789", 1000);
console.log(myAccount.getBalance()); // Output: 1000
myAccount.deposit(500);
console.log(myAccount.getBalance()); // Output: 1500
myAccount.withdraw(200);
console.log(myAccount.getBalance()); // Output: 1300
Trong ví dụ trên, chúng ta có một class BankAccount
với các thuộc tính là accountNumber
và balance
. Chúng ta chỉ có thể truy cập và thay đổi giá trị của các thuộc tính này thông qua các phương thức công khai như deposit
, withdraw
và getBalance
.
Tính kế thừa cho phép chúng ta xây dựng các lớp con dựa trên lớp cha, thừa kế các thuộc tính và phương thức của lớp cha. Trong JavaScript, chúng ta cũng có thể sử dụng class để thực hiện tính kế thừa. Dưới đây là một ví dụ:
class Animal {
constructor(name) {
this.name = name;
}
speak() {
console.log(`${this.name} is speaking.`);
}
}
class Dog extends Animal {
constructor(name, breed) {
super(name);
this.breed = breed;
}
bark() {
console.log(`${this.name} is barking.`);
}
}
const dog = new Dog("Buddy", "Golden Retriever");
dog.speak(); // Output: Buddy is speaking.
dog.bark(); // Output: Buddy is barking.
Trong ví dụ trên, chúng ta có lớp cha Animal
với thuộc tính name
và phương thức speak
. Lớp con Dog
kế thừa từ lớp cha Animal
và thêm một phương thức riêng là bark
.
Tính đa hình cho phép các đối tượng cùng kiểu có thể hiểu và thực hiện các phương thức một cách khác nhau. Trong JavaScript, chúng ta có thể sử dụng class để thực hiện tính đa hình. Dưới đây là một ví dụ:
class Shape {
calculateArea() {
// Phương thức này sẽ được ghi đè trong các lớp con
}
}
class Rectangle extends Shape {
constructor(width, height) {
super();
this.width = width;
this.height = height;
}
calculateArea() {
return this.width * this.height;
}
}
class Circle extends Shape {
constructor(radius) {
super();
this.radius = radius;
}
calculateArea() {
return Math.PI * this.radius * this.radius;
}
}
const rectangle = new Rectangle(5, 10);
const circle = new Circle(3);
console.log(rectangle.calculateArea()); // Output: 50
console.log(circle.calculateArea()); // Output: 28.274333882308138
Trong ví dụ trên, chúng ta có một lớp cha Shape
với phương thức calculateArea
. Lớp con Rectangle
và Circle
kế thừa từ lớp cha và ghi đè phương thức calculateArea
để tính diện tích cho hình chữ nhật và hình tròn.
Tính trừu tượng cho phép chúng ta định nghĩa các lớp trừu tượng mà không thể tạo ra các đối tượng từ chúng. Trong JavaScript, chúng ta không có từ khóa abstract
để định nghĩa lớp trừu tượng, nhưng chúng ta có thể sử dụng class để tạo ra tính trừu tượng. Dưới đây là một ví dụ:
class Animal {
constructor(name) {
this.name = name;
}
speak() {
console.log(`${this.name} is speaking.`);
}
}
class Dog extends Animal {
constructor(name, breed) {
super(name);
this.breed = breed;
}
speak() {
console.log(`${this.name} is barking.`);
}
}
const animal = new Animal("Generic Animal");
const dog = new Dog("Buddy", "Golden Retriever");
animal.speak(); // Output: Generic Animal is speaking.
dog.speak(); // Output: Buddy is barking.
Trong ví dụ trên, lớp Animal
là một lớp trừu tượng, không thể tạo ra đối tượng trực tiếp từ lớp này. Lớp con Dog
kế thừa từ lớp Animal
và ghi đè phương thức speak
để cho ra kết quả khác nhau.