Nội dung Bài 7 trình bày đến người học những vấn đề liên quan đến Kế thừa và Đa xạ, cụ thể như: Khái niệm về Kế thừa, khai báo lớp kế thừa đơn, quyền truy cập, kiểu kế thừa, đa kế thừa, hàm thuần ảo,...Mời các bạn cùng tham khảo!
Trang 1TRƯỜNG ĐẠI HỌC BÁCH KHOA HÀ NỘI
Ngôn ngữ lập trình C và C++
Bài 7: Kế thừa và Đa xạ
TS Đỗ Đăng Khoa
Bộ môn Cơ học Ứng dụng
Trang 2Khái niệm về Kế thừa
Kế thừa cho phép định nghĩa một lớp mới từ một lớp khác
nhằm mở rộng và sử dụng lại các thành phần dữ liệu và hàm của
lớp cũ thay vì phải viết mới hoàn toàn
Một lớp được kế thừa từ lớp khác được gọi là lớp dẫn xuất,
hoặc lớp con
Lớp cho phép việc kế thừa gọi là lớp cơ sở hoặc lớp cha
Lớp cho phép việc kế thừa gọi là lớp cơ sở hoặc lớp cha
Một lớp có thể là lớp cơ sở cho nhiều lớp dẫn xuất
Một lớp có thể kế thừa từ một hoặc nhiều lớp cơ sở
Hàm dựng và hàm hủy không được phép kế thừa cho các lớp
dẫn xuất
Con trỏ của lớp cơ sở có thể chứa được địa chỉ của các đối
Trang 3Khái niệm về Kế thừa
Lớp kế thừa mặc nhiên có thể sử dụng một phần hoặc toàn bộ
các thành phần của lớp cơ sở
Tuỳ thuộc vào kiểu kế thừa Có 3 kiểu kế thừa: public,
protected và private
Ví dụ về kế thừa:
Trang 4Khai báo lớp kế thừa đơn
Cú pháp:
class derived-class: access-specifier base-class
Trong đó:
derived-class: Tên lớp mới
access-specifier: Kiểu kế thừa là public, protected hoặc
Trang 5Khai báo lớp kế thừa đơn
Ví dụ: Lớp cơ sở Shape, và lớp dẫn xuất Rectangle
height = h;
Trang 6Khai báo lớp kế thừa đơn
class Rectangle: public Shape{
class Rectangle: public Shape{
public:
int getArea(){
return (width * height);
}};
Trang 7Khai báo lớp kế thừa đơn
int main(void){
Rectangle Rect;
Rect.setWidth(5);
Rect.setHeight(7);
// Print the area of the object
cout << "Total area: " << Rect.getArea() <<
endl;
return 0;
Trang 8Quyền truy cập
Lớp dẫn xuất có thể truy cập tất cả các thành phần không phải
private
Bảng tổng hợp các quyền truy cập
Trang 9Kiểu kế thừa
Khi dẫn xuất một lớp từ lớp cơ sở, lớp cơ sở có thể được kế
thừa theo public, protected và private
Kế thừa public: tất cả thành phần public, protected của lớp cơ
sở sẽ là thành phần public, protected tương ứng của lớp dẫn
xuất Các thành phần private của lớp cơ sở không truy cập trực
tiếp từ lớp dẫn xuất, nhưng có thể truy cập bằng cách gọi các
tiếp từ lớp dẫn xuất, nhưng có thể truy cập bằng cách gọi các
thành phần public và protected của lớp cơ sở
Kế thừa protected: Các thành phần public, protected của lớp
cơ sở sẽ là thành phần protected của lớp dẫn xuất
Kế thừa private: Các thành phần public, protected của lớp cơ
sở sẽ là thành phần private của lớp dẫn xuất
Trang 10Đa kế thừa
Một lớp có thể kế thừa các thành phần từ nhiều lớp cơ sở,
được khai báo như sau:
class derived-class: access baseA, access
Trang 11height = h;
}protected:
int width;
int height;
Trang 13{
return (width * height);
}};
Trang 14Đa kế thừa
int main(void){
Rectangle Rect; int area;
Rect.setWidth(5);
Rect.setHeight(7);
area = Rect.getArea();
// Print the area of the object
// Print the area of the object
cout << "Total area: " << Rect.getArea() <<
endl;
// Print the total cost of painting
cout << "Total paint cost: $" <<
Rect.getCost(area) << endl;
Trang 15Đa xạ (polymorphism)
Đa xạ thường xảy ra khi có một hệ thống phân cấp các lớp và
chúng có liên quan bởi việc kế thừa
Đa xạ có nghĩa là việc gọi tới một hàm thành phần sẽ làm cho
làm cho một hàm khác được thực hiện tùy thuộc vào kiểu của đối
tượng đó gọi hàm
Trang 17class Rectangle: public Shape{
class Rectangle: public Shape{
Trang 18cout << "Triangle class area :" <<endl;
cout << "Triangle class area :" <<endl;
return (width * height / 2);
}};
Trang 19// store the address of Rectangle
// store the address of Rectangle
Trang 20Hàm area() được thiết lập một lần bởi trình biên dịch là hàm của
Hàm area() được thiết lập một lần bởi trình biên dịch là hàm của
lớp cơ sở Đây được gọi là liên kết tĩnh – hàm gọi được đã xác
định trước khi chương trình thực hiện
Để giải quyết vấn đề, bổ sung thêm từ khóa virtual trước
hàm area của lớp Shape:
virtual int area()
Trang 21Đa xạ (polymorphism)
Kết quả in ra:
Rectangle class areaTriangle class area
Với từ khóa virtual, trình biên dịch tìm kiếm nội dung của con
trỏ thay vì kiểu của nó Do đó, từ lúc địa chỉ của các lớp Triangle
và Rectangle được chứa trong *shape, hàm area tương ứng sẽ
và Rectangle được chứa trong *shape, hàm area tương ứng sẽ
được gọi
Chúng ta có các lớp với một hàm tên giống nhau, thậm chí cùng
tham số, nhưng được triển khai khác nhau Đây là cách đa xạ
thường được dùng
Trang 22Hàm ảo (Virtual Function)
Hàm ảo là hàm trong lớp cơ sở được khai báo sử dụng từ khóa
virtual
Việc định nghĩa một hàm ảo trong lớp cơ sở, một hàm tương tự
trong lớp dẫn xuất nhằm nói với trình biên dịch hàm này không
được liên kết tĩnh mà là liên kết động
Hàm ảo không dùng cho hàm dựng nhưng có dùng cho hàm
Hàm ảo không dùng cho hàm dựng nhưng có dùng cho hàm
hủy
Trang 23Hàm thuần ảo
Hàm thuần ảo được khai báo như sau:
virtual kiểu tên_hàm() = 0;
Hàm thuần ảo không có thân hàm
Khai báo hàm thuần ảo trong lớp cơ sở nhằm yêu cầu các lớp
dẫn xuất từ lớp này bắt buộc phải có phần triển khai riêng hàm
đó
đó