### Khái niệm đa hình (Polymorphism) trong C++
Đa hình là một tính năng trong lập trình hướng đối tượng (OOP) cho phép các đối tượng khác nhau được xử lý bằng cùng một giao diện, nhưng có thể thực hiện các hành vi khác nhau. Đa hình giúp tăng tính linh hoạt và khả năng mở rộng của chương trình.
### Có hai loại đa hình trong C++:
1. **Đa hình tĩnh (Compile-time Polymorphism):**
- Được thực hiện thông qua **nạp chồng hàm (function overloading)** và **nạp chồng toán tử (operator overloading)**.
- Các hàm có cùng tên nhưng khác tham số sẽ được gọi tùy thuộc vào tham số truyền vào.
**Ví dụ:**
```cpp
#include
using namespace std;
class Math {
public:
int add(int a, int b) {
return a + b;
}
double add(double a, double b) {
return a + b;
}
};
int main() {
Math math;
cout << math.add(5, 3) << endl; // Gọi hàm thêm cho int</p>
cout << math.add(5.5, 3.2) << endl; // Gọi hàm thêm cho double</p>
return 0;
}
```
2. **Đa hình động (Runtime Polymorphism):**
- Được thực hiện thông qua việc sử dụng **hàm ảo (virtual function)** và **kế thừa**.
- Cho phép lớp con ghi đè (override) hàm của lớp cha và determinate cách thức gọi hàm vào thời điểm chạy.
**Ví dụ:**
```cpp
#include
using namespace std;
class Animal {
public:
virtual void sound() { // Hàm ảo
cout << "Động vật phát ra âm thanh!" << endl;</p>
}
};
class Dog : public Animal {
public:
void sound() override { // Ghi đè hàm
cout << "Chó sủa: Woof!" << endl;</p>
}
};
class Cat : public Animal {
public:
void sound() override { // Ghi đè hàm
cout << "Mèo kêu: Meow!" << endl;</p>
}
};
void makeSound(Animal* animal) {
animal->sound(); // Gọi phương thức sound()
}
int main() {
Dog myDog;
Cat myCat;
makeSound(&myDog); // In ra "Chó sủa: Woof!"
makeSound(&myCat); // In ra "Mèo kêu: Meow!"
return 0;
}
```
### Giải thích mã:
- **Đa hình tĩnh:** Trong ví dụ trên, lớp `Math` có hai phương thức `add()` với tham số khác nhau, cho phép thực hiện phép cộng cho cả số nguyên và số thực.
- **Đa hình động:** Lớp `Animal` định nghĩa hàm ảo `sound()`, và các lớp con `Dog` và `Cat` ghi đè nó. Hàm `makeSound()` nhận một con trỏ đến lớp `Animal`, nhưng tại thời điểm gọi, phương thức cụ thể tương ứng với đối tượng đang được sử dụng sẽ được gọi.