### Sự khác nhau giữa kế thừa đa cấp và kế thừa đa hình trong C++
#### 1. Kế thừa đa cấp (Multilevel Inheritance)
**Khái niệm**: Kế thừa đa cấp là kiểu kế thừa trong đó một lớp dẫn xuất (derived class) kế thừa từ một lớp cơ sở (base class), và sau đó lớp dẫn xuất này lại trở thành lớp cơ sở cho một hoặc nhiều lớp dẫn xuất khác.
**Ví dụ minh họa**:
```cpp
#include <iostream>
using namespace std;
// Lớp cơ sở
class Animal {
public:
void eat() {
cout << "Animal eats." << endl;
}
};
// Lớp dẫn xuất từ Animal
class Dog : public Animal {
public:
void bark() {
cout << "Dog barks." << endl;
}
};
// Lớp dẫn xuất từ Dog
class Puppy : public Dog {
public:
void weep() {
cout << "Puppy weeps." << endl;
}
};
int main() {
Puppy myPuppy;
myPuppy.eat(); // Gọi từ lớp Animal
myPuppy.bark(); // Gọi từ lớp Dog
myPuppy.weep(); // Gọi từ lớp Puppy
return 0;
}
```
#### 2. Kế thừa đa hình (Polymorphism)
**Khái niệm**: Kế thừa đa hình cho phép các đối tượng thuộc các lớp khác nhau được xử lý như thể chúng thuộc cùng một lớp cơ sở. Điều này thường được thực hiện thông qua hàm ảo, cho phép gọi hàm của lớp dẫn xuất thông qua con trỏ hoặc tham chiếu của lớp cơ sở.
**Ví dụ minh họa**:
```cpp
#include <iostream>
using namespace std;
// Lớp cơ sở
class Shape {
public:
virtual void draw() { // Hàm ảo
cout << "Drawing a shape." << endl;
}
};
// Lớp dẫn xuất từ Shape
class Circle : public Shape {
public:
void draw() override { // Ghi đè hàm ảo
cout << "Drawing a circle." << endl;
}
};
// Lớp dẫn xuất từ Shape
class Square : public Shape {
public:
void draw() override { // Ghi đè hàm ảo
cout << "Drawing a square ```cpp
." << endl;
}
};
int main() {
Shape* shape1 = new Circle(); // Tạo đối tượng Circle
Shape* shape2 = new Square(); // Tạo đối tượng Square
shape1->draw(); // Gọi hàm draw của Circle
shape2->draw(); // Gọi hàm draw của Square
// Giải phóng bộ nhớ
delete shape1;
delete shape2;
return 0;
}
```
### Tóm tắt sự khác nhau giữa kế thừa đa cấp và kế thừa đa hình
| Tiêu chí | Kế thừa đa cấp | Kế thừa đa hình |
|--------------------------|-----------------------------------------|-----------------------------------------|
| **Khái niệm** | Một lớp dẫn xuất kế thừa từ một lớp cơ sở, và lớp dẫn xuất này lại trở thành lớp cơ sở cho các lớp khác. | Cho phép xử lý các đối tượng thuộc các lớp khác nhau như thể chúng thuộc cùng một lớp cơ sở. |
| **Mục đích** | Tạo ra cấu trúc phân cấp giữa các lớp. | Cung cấp khả năng gọi hàm của lớp dẫn xuất thông qua con trỏ hoặc tham chiếu của lớp cơ sở. |
| **Sử dụng hàm ảo** | Không nhất thiết phải sử dụng hàm ảo. | Sử dụng hàm ảo để đạt được tính đa hình động. |