Dđiều nào sau đây mô tả tính da kế thừa năm 2024
Một trong những đặc tính quan trọng nhất của OOP là kế thừa. Ưu điểm của đặc tính kế thừa: sử dụng lại các đoạn code đã có trong chương trình 1 cách hiệu quả. Khi tạo 1 class, thay vì việc viết 1 class mới hoàn toàn, người lập trình viên có thể kế thừa một số thuộc tính và phương thức từ 1 class đã có trong project. Class đã có trước đấy gọi là lớp cơ sở (Base Class), class kế thừa từ Base Class (hay superclass) gọi là lớp dẫn xuất (Derived Class). Do tính kế thừa khá rõ ràng và dễ hiểu nên mình sẽ không giải thích nhiều về kế thừa nữa. Bạn nào muốn tìm hiểu thêm thì tham khảo link này nhé: https://www.cppdeveloper.com/c-co-ban/6-1-1-dinh-nghia-mot-phan-lop-don-gian-1/ Tính đa hình – PolymorphismTính Đa hình – Polymorphism là một tính chất đặc trưng rất thần thánh của OOP. Trong bài này mình sẽ chủ yếu tập trung giải thích về Polymorphism cho các bạn. Đầu tiên mình sẽ đưa ví dụ về Polymorphism ở ngoài đời thực để anh em dễ hình dung đã. Ví dụ, cùng là một người nhưng tuỳ từng ngữ cảnh sẽ đóng vai trò khác nhau, một người đàn ông vừa là nhân viên (khi đi làm), vừa là một người chồng (đối với vợ) và là người cha (đối với con),… nói chung là anh ta sẽ biến hình thành con người khác nhau tuỳ từng ngữ cảnh. Trong OOP và cụ thể là trọng ngôn ngữ C++ thì Polymorphism có 2 dạng:
Sau đây mình sẽ đưa code sample cho 2 dạng Polymorphism ở trên. — Sample 1 – Compile time Polymorphism 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 include using namespace std; class PrintData { public: void print(int i) { cout << "Printing int: " << i << endl; } void print(double f) { cout << "Printing float: " << f << endl; } void print(char* c) { cout << "Printing character: " << c << endl; } }; int main(void) { PrintData pd; pd.print(5);// Call print to print integer pd.print(500.263);// Call print to print float pd.print("Hello C++");// Call print to print character return 0; } Ta có class PrintData có 3 phương thức cùng tên là print(), 3 phương thức này cùng có một tham số nhưng kiểu của tham số thì khác nhau, lần lượt là int, double và char*. Trong hàm main gọi đến phương thức print() 3 lần với 3 tham số khác nhau, khi đó trình biên dịch sẽ dựa vào kiểu ‘(hoặc giá trị) của tham số truyền vào và tự quyết định phương thức nào trong 3 phương thức cùng tên sẽ được gọi. Chương trình này chạy sẽ ra kết quả trên console như sau: Printing int: 5 Printing float: 500.263 Printing character: Hello C++ — Sample 2 – Runtime Polymorphism 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 35 include using namespace std; class Pet { protected: string Name; public: Pet(string n) { Name \= n; } virtual string getSound() { return "";}; void makeSound(void) { cout << Name << "says: " << getSound() << endl; } }; class Cat : public Pet { public: Cat(string n) : Pet(n) { } string getSound() { return "Meow! Meow!";}; }; class Dog : public Pet { public: Dog(string n) : Pet(n) { } string getSound() { return "Woof! Woof!";}; }; int main(void) { Pet *a_pet \= new Cat("Kitty");; a_pet-\>makeSound(); delete a_pet; a_pet \= new Dog("Doggie"); a_pet-\>makeSound(); delete a_pet; return 0; } Chương trình này sẽ xuất ra màn hình nội dung như sau → Kitty says: Meow! Meow! Doggie says: Woof! Woof! Ở đây ta có class cha là Pet định nghĩa phương thức makeSound(), phương thức này đưa ra mô tả về tiếng kêu của con vật. Tiếng kêu được định nghĩa bởi hàm getSound(), hàm này được khai báo là hàm ảo (virtual) ở class cha, điều đó cho phép các class con như Cat, Dog định nghĩa lại (overriding) hàm này cho phù hợp với đặc điểm riêng của chúng. Chính vì vậy ở hàm main dù cùng là con trỏ a_pet nhưng khi gọi hàm makeSound() 2 lần lại ra 2 nội dung khác nhau tuỳ thuộc vào đối tượng đang được trỏ tới lúc đó là đối tượng của class con nào (Dog hay Cat) |