0

Tính thừa kế

43 536 0
  • Tính thừa kế

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

Tài liệu liên quan

Thông tin tài liệu

Ngày đăng: 21/08/2012, 15:34

Bài giảng lập trình hướng đối tượng - Thầy Cường Học viện bưu chính viễn thông TP HCM 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'; } }; [...]... Đ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 kế thừa 193 Kết quả của chương trình ? Ví dụ 5.3 Minh họa thứ tự gọi các hàm tạo và hàm hủy khi lớp dẫn xuất kế thừa trực tiếp nhiều lớp cơ sở. #include <iostream.h> class B1 { public: B1() {... 0; } @ Nếu derived1 và derived2 không kế thừa base như một lớp ảo thì câu lệnh ob.i = 10; sẽ không rõ ràng và sẽ tạo ra lỗi thời gian biên dịch. • Khi một lớp cơ sở được kế thừa như một lớp ảo bởi một lớp dẫn xuất thì lớp cơ sở đó vẫn còn tồn tại trong lớp dẫn xuất . 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ở... D. o2.c = 10 ; 2. Điều gì xảy ra khi một thành viên riêng được kế thừa như một thành viên chung ? Điều gì xảy ra khi nó được kế thừa như một thành viên riêng ? Chương 6 Tính kế thừa 194 Constructing B2 Constructing D Destructing D Destructing B2 Destructing B1 Baøi tập V 1. Cho đoạn chương trình sau, hãy khảo sát kết quả của chương trình ? #include <iostream.h> class... char name[40]; }; Chương 6 Tính kế thừa 190 } base1 , base2, , baseN tên các lớp cơ sở access chỉ định truy cập, có thể khác nhau đối với mỗi lớp Khi nhiều lớp cơ sở được kế thừa, các hàm tạo được thi hành theo thứ tự từ trái qua phải mà các lớp cơ sở đã được chỉ định rõ. Các hàm hủy được thi hành theo thứ tự ngược lại. • Khi một lớp kế thừa nhiều lớp cơ sở có các hàm tạo... "; out(eating); cout << "\n"; } Chương 6 Tính kế thừa 201 1. Hãy tạo lớp cơ sở chung building để lưu trữ số tầng nhà mà một toà nhà có số phòng và số tổng diện tích dưới dạng protected. Hãy tạo lớp dẫn xuất house kế thừa building và lưu trữ số phòng ngũ và phòng tắm. Cũng vậy, tạo lớp dẫn xuất office kế thừa public lớp building và lưu trữ số bình cứu hoả và số máy điện... chạy tốt Chương 6 Tính kế thừa 196 Khi nhiều lớp cơ sở được kế thừa trực tiếp bởi một lớp dẫn xuất, tồn tại một vấn đề : xuất hiện nhiều bản sao của lớp cơ sở cùng hiện diện trong đối tượng dẫn xuất. Chẳng hạn, xét hệ thống thứ bậc lớp sau Bời vì có hai bản sao của B trong D3, nên một tham chiếu đến một thành viên của B sẽ tham chiếu về B được kế thừa gián tiếp thông qua... truck t(30000, 12, 1200); cout << "Car: \n"; c.show(); cout << "\nTruck:\n"; t.show(); return 0; } V/ Tính đa kế thừa Chương 6 Tính kế thừa 187 car ob(passengers, wheels, range) ; truck ob(loadlimit, wheels, range) ; #include <iostream.h> // A base class for various types of vehicles. class vehicle... << "Destructing D\n"; } }; int main() { D ob; return 0; } Giải thích kết quả của chương trình ? Constructing B1 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... 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 164 Chương 6 Tính kế thừa 188 showv(); cout << "loadlimit " << loadlimit << '\n'; } }; int main() { car c(5,... base_ob is of type base Ví dụ 2.4 Lớp dẫn xuất kế thừa lớp cơ sở với chỉ định private, các thành viên vẫn còn được truy cập bên trong lớp dẫn xuất. // This program is fixed. #include <iostream.h> class base { int x; public: void setx(int n) { x = n; } void showx() { cout << x << '\n'; } }; Chương 6 Tính kế thừa 166 // Define base class. class base . 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. 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ế
- Xem thêm -

Xem thêm: Tính thừa kế , Tính thừa kế , Tính thừa kế

Hình ảnh liên quan

1. Lập bảng tổng kết về quyền truy cập của lớp dẫn xuất với sự kế thừa đơn Thuộc tính thành viên  - Tính thừa kế

1..

Lập bảng tổng kết về quyền truy cập của lớp dẫn xuất với sự kế thừa đơn Thuộc tính thành viên Xem tại trang 18 của tài liệu.