Chúng tôi đã sửa lại ví dụ ở trang trước. Chúng ta vẫn có hai class là Dog và Cat, nhưng chúng ta đã đặt chúng vào cùng một cây thừa kế. Hãy xem →
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
#include <iostream> #include <string> using namespace std; class Pet { protected: string Name; public: Pet(string n) { Name = n; } void Run(void) { cout << Name << ": I'm running" << endl; } }; class Dog : public Pet { public: Dog(string n) : Pet(n) {}; void MakeSound(void) { cout << Name << ": Woof! Woof!" << endl; } }; class Cat : public Pet { public: Cat(string n) : Pet(n) {}; void MakeSound(void) { cout << Name << ": Meow! Meow!" << endl; } }; int main(void) { Pet a_pet("pet"); Cat a_cat("Tom"); Dog a_dog("Spike"); a_pet.Run(); a_dog.Run(); a_dog.MakeSound(); a_cat.Run(); a_cat.MakeSound(); return 0; } |
Các lớp Dog và Cat bây giờ cùng là hậu duệ của một lớp cơ sở là Pet. Tất cả các class đều đã được trang bị hàm khởi tạo, cho phép chúng ta cung cấp tên cho tất cả các đối tượng sẽ được tạo ra.
Hãy tóm tắt những gì chúng ta tạo ra:
- Các đối tượng có nguồn gốc từ lớp Pet có thể chạy
- Các đối tượng có nguồn gốc từ các lớp Dog và Cat có thể chạy (chúng kế thừa khả năng này từ lớp cha của chúng); chúng cũng có thể tạo ra âm thanh (lưu ý rằng kỹ năng này không có sẵn cho các đối tượng của lớp Pet)
Và như vậy:
- Cat và Dog có thể làm tất cả những gì mà Pet có thể làm
- Pet không thể làm tất cả những gì mà Cat và Dog có thể làm
Chúng ta sẽ nói lại lần nữa, nhưng lần này sử dụng ít thuật ngữ về “động vật” hơn:
- Các đối tượng của phân lớp (lớp con) luôn có các khả năng giống như các đối tượng lớp cơ sở (lớp cha)
- Các đối tượng của lớp cơ sở (lớp cha) có thể không có khả năng giống như các đối tượng của phân lớp (lớp con)
Điều này dẫn chúng ta tới kết luận sau:
- Các đối tượng của lớp cơ sở (lớp cha) tương thích với các đối tượng của phân lớp (lớp con)
- Các đối tượng của phân lớp (lớp con) không tương thích với các đối tượng của lớp cơ sở (lớp cha)
Điều này có nghĩa rằng:
- Bạn có thể thực hiện các lệnh sau:
1 2 |
a_pet = new Dog("Huckleberry"); a_pet -> Run(); |
nhưng không được làm như thế này
1 |
a_pet -> MakeSound(); |
bởi vì Pet không biết làm thế nào để tạo ra âm thanh.
- Bạn không được phép thực hiện các lệnh sau:
1 |
a_dog = new Pet("Strange pet"); |
Hãy quay trở lại với chương trình ví dụ bên trên, nó sẽ cho ra kết quả như sau:
1 2 3 4 5 |
pet: I'm running Spike: I'm running Spike: Woof! Woof! Tom: I'm running Tom: Meow! Meow! |