Lập Trình C++ B13: Tính Đa Hình Trong Lập Trình C++
Tính đa hình trong c++
Khi học lập trình c++, và bắt đầu đến kỹ thuật lập trình hướng đối tượng,
các bạn nắm vững các kiến thức cơ bản về lập trình hướng đối tượng.
Trong đó các tính chất về của lập trình hướng đối tượng là rất quan trọng và cần thiết.
Chủ đề này các bạn sẽ làm quen với những khái niệm như:
Phương thức ảo.
Phương thức trừu tượng.
Lớp trừu tượng, phương thức thuần ảo.
Tôi nghĩ chắc hẳn các bản sẽ ôm đầu, và kêu lên rằng, thực sự đọc chẳng hiểu gì cả.
1. Đặt vấn đề cho sự ra đời của tính đa hình trong c++.
Một ông bố có 1 người con.
Case 1:
Cả bố và con đều cùng biết làm một việc có tên là A.
Nhưng cách làm của 2 người khác nhau và cho ra những kết quả khác nhau.
Một ai đó muốn ông bố tự mình làm việc A => rất đơn giản chỉ việc yêu cầu ông bố thực hiện
Một ai đó muốn ông con tự mình làm việc A => rất đơn giản chỉ việc yêu cầu ông con thực hiện.
+ Nhưng nếu 1 ai đó muốn thông qua ông bố, điều khiển ông con tự làm việc A của ông con => Vậy thì sẽ thế nào.
+ Hoặc 1 ai đó muốn từ ông bố làm việc A của ông bố,
đồng thời sau đó cũng điều khiển luôn được ông con làm việc A của ông con,
kết quả thu được là của cả 2 người => Vậy sẽ làm thế nào.
Case 2:
Chỉ có ông con làm được việc A, còn ông bố không biết làm việc A nhưng lại chém gió rằng, mình có thể làm được việc A.
Và khi một ai đó yêu cầu ông bố làm việc A, ông bố sẽ truyền sang cho ông con làm và chỉ việc chờ đợi và thu về kết quả.
=> Vậy sẽ làm thế nào.
Từ bài toán thực tế ở trên, áp dụng vào kỹ thuật lập trình hướng đối tượng cũng vậy.
Bố là lớp cha, hay còn gọi là lớp cơ sở.
Con là lớp kế thừa, hay còn gọi là lớp dẫn xuất.
Để giải quyết được kỹ thuật “Vậy sẽ làm thế nào” ở bài toán trên.
Tính đa hình được xây dựng. Và đó là một kỹ thuật tiêu biểu, phổ biến trong lập trình hướng đối tượng với c++.
2. Lý thuyết tính đa hình trong hướng đối tượng.
Trong ví dụ dưới đây. Tôi có một lớp cha, và một lớp con kế thừa từ cha.
class Father { public: virtual void ImpCooking(); protected: int x_; int y_; }; void Father::ImpCooking() { std::cout << "I can cook fish"<< std::endl; } class Son : public Father { public: void ImpCooking(); }; void Son::ImpCooking() { std::cout << "I can cook pork"<< std::endl; }
Cả lớp Father và lớp Son đều có phương thức ImpCooking.
=> Để sử dụng tính đa hình cho phương thức ImpCooking thì tôi phải dùng từ khóa virtual đặt trước phương thức này.
Virtual nghĩa là ảo: Do đó ImpCooking được gọi là một hàm ảo, Father được gọi là một lớp cơ sở ảo.
Trong lớp con cũng sẽ định nghĩa một hàm ImpCooking như vậy để thực hiện tính đa hình.
Vậy thì để sử dụng tính đa hình thì sử dụng như thế nào.
2.1. Gọi lớp cha, và chỉ gọi ImpCooking của cha. (Phương thức truy nhập bình thường, không có tính đa hình)
2.2 Khai báo lớp cha nhưng chỉ gọi đến function của con.
Đây chính là kỹ thuật đa hình.
Mấu chốt của tính chất chính là chúng ta sử dụng đối tượng lớp cha,
nhưng cấp phát vùng nhớ cho nó kiểu dữ liệu lớp con. Và nó sẽ gọi đến hàm của lớp con.
2.3 Nếu muốn gọi lớp con và sau đó cũng gọi đến lớp cha.
Thì chúng ta chỉ cần đặt hàm gọi lớp cha trong hàm của lớp con như sau.
2.3 Lớp Cha chỉ khởi tạo hàm, mà không định nghĩa hàm, mà chỉ có lớp con định nghĩa hàm, thông qua cha để gọi con.
Đây được gọi là tính chất virtual pure trong lập trình hướng đối tượng.
Nghĩa là, lớp cha là một lớp thuần ảo, nghĩa là chỉ khởi tạo, mà không hề có định nghĩa gì
và người ta sẽ làm như sau:
Các bạn sẽ thấy, sau function ImpCooking tôi gán function này = giá trị 0
Như vậy, tôi không cần định nghĩa hàm này trong lớp cơ mà chỉ cần định nghĩa trong lớp con là đủ.
Và đương nhiên kết quả chỉ là kết quả của lớp con.
Như vậy tính đa hình là kỹ thuật thể hiện nhiều hình ảnh của một đối tượng.
Một đối tượng là của một lớp, nhưng có thể cho ra các kế quả khác, đó được gọi là các hình ảnh khác nhau.
Tính đa hình cũng được sử dụng rộng rãi trong các dự án phần mềm c++, đặc biệt là trong mảng lập trình đồ họa 3d.
Một lớp cha có vô vàn các lớp con, và tính đa hình sẽ được tận dụng triệt để trong hoàn cảnh này.
End.