Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống
1
/ 43 trang
THÔNG TIN TÀI LIỆU
Thông tin cơ bản
Định dạng
Số trang
43
Dung lượng
71,25 KB
Nội dung
Chương 6 Tính kế thừa • Giới thiệu tính kế thừa • Điều khiển truy cập lớp cơ sở • Sử dụng các thành viên được bảo vệ • Hàm tạo, hàm hủy và tính kế thừa • Tính đa kế thừa • Lớp cơ sở ảo Chöông 6 Tính keá thöøa 164 Chương 6 Tính kế thừa 165 I/ Giới thiệu tính kế thừa (inheritance) Tính kế thừa là cơ chế nhờ đó một lớp có thể kế thừa các đặc điểm của một lớp khác. Tính kế thừa hổ trợ khái niệm phân loại theo thứ bậc (hierachical classification) của lớp, ngoài ra còn hổ trợ tính đa hình (polymorphism). • Lớp cơ sở (base class) là lớp được kế thừa bởi một lớp khác. Lớp dẫn xuất (derive class) là lớp kế thừa từ một lớp cơ sở. Lớp cơ sở xác đònh các tính chất mà sẽ trở nên thông dụng cho các lớp dẫn xuất. Nghiã là lớp cơ sở hiển thò mô tả tổng quát nhất một tập hợp các đặc điểm. Một lớp dẫn xuất kế thừa các đặc điểm tổng quát này và bổ sung thêm các tính chất riêng của lớp dẫn xuất. Cú pháp khai báo cho lớp dẫn xuất class derived_class_name : access_specifier base_class_name { // body of class } ; base_class_name Tên lớp cơ sở derived_class_name Tên lớp dẫn xuất access_specifier chỉ đònh truy cập bao gồm : public , private và protected • Từ khoá public báo cho trình biên dòch biết rằng lớp cơ sở sẽ được kế thừa sao cho mọi thành viên chung của lớp cơ sở cũng sẽ là các thành viên chung của lớp dẫn xuất . Tuy nhiên, mọi thành viên riêng của lớp cơ sở vẫn còn riêng đối với nó và không được truy cập trực tiếp bởi lớp dẫn xuất. Ví dụ 1.1 // A simple example of inheritance. #include <iostream.h.h> B D Hình 6.1 Sự kế thừa đơn Chöông 6 Tính keá thöøa 166 // Define base class. class base { int i; public: void set_i(int n); int get_i(); }; // Define derived class. class derived : public base { int j; public: void set_j(int n); int mul(); }; // Set value i in base. void base::set_i (int n) { i = n; } // Return value of i in base. int base::get_i () { return i; } // Set value of j in derived. void derived::set_j (int n) { j = n; } // Return value of base's i times derived's j. int derived::mul () { // derived class can call base class public member functions return j * get_i(); } Chương 6 Tính kế thừa 167 int main() { derived ob; ob.set_i(10); // load i in base ob.set_j(4); // load j in derived cout << ob.mul(); // displays 40 return 0; } • Một lớp cơ sở là không thuộc riêng về một lớp dẫn xuất. Lớp cơ sở có thể được kế thừa bởi nhiều lớp khác . Ví dụ 1.2 Lớp cơ sở chung Fruit có 2 lớp dẫn xuất Apple và Orange // An example of class inheritance. #include <iostream.h.h> #include <string.h> enum yn {no, yes}; enum color {red, yellow, green, orange}; void out(enum yn x); char *c[] = {"red", "yellow", "green", "orange"}; // Generic fruit class. class fruit { // in this base, all elements are public public: enum yn annual; enum yn perennial; enum yn tree; enum yn tropical; enum color clr; char name[40]; }; Chöông 6 Tính keá thöøa 168 // Derive Apple class. class Apple : public fruit { enum yn cooking; enum yn crunchy; enum yn eating; public: void seta(char *n, enum color c, enum yn ck, enum yn crchy, enum yn e); void show(); }; // Derive orange class. class Orange : public fruit { enum yn juice; enum yn sour; enum yn eating; public: void seto(char *n, enum color c, enum yn j, enum yn sr, enum yn e); void show(); }; void Apple::seta (char *n, enum color c, enum yn ck, enum yn crchy, enum yn e) { strcpy(name, n); annual = no; perennial = yes; tree = yes; tropical = no; clr = c; cooking = ck; crunchy = crchy; eating = e; } void Orange::seto (char *n, enum color c, enum yn j, enum yn sr, enum yn e) { strcpy(name, n); Chöông 6 Tính keá thöøa 169 annual = no; perennial = yes; tree = yes; tropical = yes; clr = c; juice = j; sour = sr; eating = e; } void Apple::show () { cout << name << " apple is: " << "\n"; cout << "Annual: "; out(annual); cout << "Perennial: "; out(perennial); cout << "Tree: "; out(tree); cout << "Tropical: "; out(tropical); cout << "Color: " << c[clr] << "\n"; cout << "Good for cooking: "; out(cooking); cout << "Crunchy: "; out(crunchy); cout << "Good for eating: "; out(eating); cout << "\n"; } void Orange::show () { cout << name << " orange is: " << "\n"; cout << "Annual: "; out(annual); cout << "Perennial: "; out(perennial); cout << "Tree: "; out(tree); cout << "Tropical: "; out(tropical); cout << "Color: " << c[clr] << "\n"; cout << "Good for juice: "; out(juice); cout << "Sour: "; out(sour); cout << "Good for eating: "; out(eating); cout << "\n"; } Chương 6 Tính kế thừa 170 void out(enum yn x) { if(x==no) cout << "no\n"; else cout << "yes\n"; } int main() { Apple a1, a2; Orange o1, o2; a1.seta("Red Delicious", red, no, yes, yes); a2.seta("Jonathan", red, yes, no, yes); o1.seto("Navel", orange, no, no, yes); o2.seto("Valencia", orange, yes, yes, no); a1.show(); a2.show(); o1.show(); o2.show(); return 0; } Bài tập I 1. Cho lớp cơ sở sau class area_cl { public: double height; double width; }; hãy tạo 2 lớp dẫn xuất box và isosceles kế thừa lớp area_cl. Với mỗi lớp hãy tạo hàm area() lần lượt trả về diện tích của một hộp hay một tam giác cân. Dùng các hàm tạo được tham số hoá để khởi đầu height và width. Chương 6 Tính kế thừa 171 II/ Điều khiển truy cập lớp cơ sở Chỉ đònh truy cập ( access_specifier ) xác đònh cách mà các phần tử của lớp cơ sở được kế thừa bởi lớp dẫn xuất. • Từ khoá private chỉ đònh các thành viên chung lớp cơ sở trở thành các thành viên riêng của lớp dẫn xuất, nhưng những thành viên này vẫn còn được truy cập bởi các hàm thành viên của lớp dẫn xuất. Ví dụ 2.1 #include <iostream.h> class base { int x; public: void setx(int n) { x = n; } void showx() { cout << x << '\n'; } }; // Inherit as public. class derived : public base { int y; public: void sety(int n) { y = n; } void showy() { cout << y << '\n'; } }; int main() { derived ob; ob.setx(10); // access member of base class ob.sety(20); // access member of derived class ob.showx(); // access member of base class ob.showy(); // access member of derived class Chương 6 Tính kế thừa 172 return 0; } Ví dụ 2.2 Lớp dẫn xuất không thể truy cập đến các thành viên riêng của lớp cơ sở class base { int x; public: void setx(int n) { x = n; } void showx() { cout << x << '\n'; } }; // Inherit as public - this has an error! class derived : public base { int y; public: void sety(int n) { y = n; } /* Cannot access private member of base class. x is a private member of base and not available within derived. */ void show_sum() { cout << x + y << '\n'; } // Error! void showy() { cout << y << '\n'; } }; Ví dụ 2.3 Lớp dẫn xuất kế thừa lớp cơ sở với chỉ đònh private // This program contains an error. #include <iostream.h> class base { int x; public: void setx(int n) { x = n; } void showx() { cout << x << '\n'; } }; [...]... myderived ob("hello"); ob.show(); cout . sở ảo Chöông 6 Tính keá thöøa 164 Chương 6 Tính kế thừa 165 I/ Giới thiệu tính kế thừa. quả của chương trình ? Chương 6 Tính kế thừa 182 Constructing base class Constructing derived class Destructing derived class Destructing base class Ví dụ 4.2 Truyền một đối số cho. ob.showxy(); return 0; } Chương 6 Tính kế thừa 175 Bài tập II 1. Xét đoạn chương trình sau #include <iostream.h> class mybase { int a,