Bài giảng Lập trình hướng đối tượng - 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

 

pdf43 trang | Chuyên mục: C/C++ | Chia sẻ: tuando | Lượt xem: 419 | Lượt tải: 0download
Tóm tắt nội dung Bài giảng Lập trình hướng đối tượng - Chương 6: Tính kế thừa, để xem tài liệu hoàn chỉnh bạn click vào nút "TẢI VỀ" ở trên
ãy khảo sát kết quả của chương trình ? 
#include 
class A { 
public: 
 A() { cout << "Constructing A\n"; } 
 ~A() { cout << "Destructing A\n"; } 
}; 
class B { 
public: 
 B() { cout << "Constructing B\n"; } 
 ~B() { cout << "Destructing B\n"; } 
}; 
class C : public A, public B { 
public: 
 C() { cout << "Constructing C\n"; } 
 ~C() { cout << "Destructing C\n"; } 
}; 
int main() 
{ 
 C ob; 
 return 0; 
} 
Chương 6 Tính kế thừa 
195 
2. Sử dụng hệ thống thứ bậc lớp sau đây, hãy lập hàm tạo cua lớp C để cho nó khởi 
đầu k và truyền các đối số cho A() và B() 
#include 
class A { 
 int i; 
public: 
 A(int a) { i = a; } 
}; 
class B { 
 int j; 
public: 
 B(int a) { j = a; } 
}; 
class C : public A, public B { 
 int k; 
public: 
 // Create C() so that it initializes k and passes arguments to both A() and B() 
 ... 
}; 
VI/ Lớp cơ sở ảo (virtual base class) 
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 D1 hay tham chiếu về B được 
kế thừa gián tiếp thông qua D2 ? 
Để giải quyết tính không rõ ràng này, C++ có một cơ chế mà nhờ đó chỉ có một bản 
sao của B ở trong D3. Đặc điểm này được gọi là lớp cơ sở ảo. 
Có thể ngăn chặn được hai bản sao của lớp cơ sở cùng hiện diện trong đối tượng dẫn 
xuất bằng cách cho lớp cơ sở đó được kế thừa như virtual bởi bất kỳ các lớp dẫn 
xuất nào. 
• Từ khoá virtual đứng trước chỉ định truy cập lớp cơ sở khi nó được kế thừa bởi 
một lớp dẫn xuất. 
Ví dụ 6.1 
// This program uses a vir
#include 
class base { 
public: 
 int i; 
}; 
// Inherit base as virtual. 
 B B 
D1 D2 
D3tual base class. 
Chương 6 Tính kế thừa 
197 
class derived1 : virtual public base { 
public: 
 int j; 
}; 
// Inherit base as virtual, here too. 
class derived2 : virtual public base { 
public: 
 int k; 
}; 
// Here, derived3 inherits both derived1 and derived2. 
// However, only one copy of base is present. 
class derived3 : public derived1, public derived2 { 
public: 
 int product() { return i * j * k; } 
}; 
int main() 
{ 
 derived3 ob; 
 ob.i = 10; // unambiguous because only one copy present 
 ob.j = 3; 
 ob.k = 5; 
 cout << "Product is " << ob.product() << '\n'; 
 return 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 
198 
Qua ví dụ 6.1 đoạn chương trình sau vẫn hoàn toàn đúng 
derived1 ob; 
ob.i = 100; 
• Sự khác biệt duy nhất giữa lớp cơ sở thường với lớp cơ sở ảo xảy ra khi một đối 
tượng kế thừa lớp cơ sở hơn một lần. Nếu các lớp cơ sở ảo được sử dụng thì chỉ 
có một lớp cơ sở hiện diện trong đối tượng. Ngược lại, nhiều bản sao sẽ được tìm 
thấy. 
Bài tập VI 
1. Trong ví dụ 6.1, bỏ từ khoá virtual và thử biên dịch chương trình. Khảo sát lổi ? 
2. Hãy sửa lỗi đoạn chương trình sau 
// A variation on the vehicle hierarchy. But this program contains an error. Fix it. 
// Hint : try compiling it as is and observe the error messages. 
#include 
// A base class for various types of vehicles. 
class vehicle { 
 int num_wheels; 
 int range; 
public: 
 vehicle(int w, int r) 
 { 
 num_wheels = w; range = r; 
 } 
 void showv() 
 { 
 cout << "Wheels: " << num_wheels << '\n'; 
 cout << "Range: " << range << '\n'; 
 } 
Chương 6 Tính kế thừa 
199 
}; 
enum motor {gas, electric, diesel}; 
class motorized : public vehicle { 
 enum motor mtr; 
public: 
 motorized(enum motor m, int w, int r) : vehicle(w, r) { 
 mtr = m; 
 } 
 void showm() { 
 cout << "Motor: "; 
 switch(mtr) { 
 case gas : cout << "Gas\n"; 
 break; 
 case electric : cout << "Electric\n"; 
 break; 
 case diesel : cout << "Diesel\n"; 
 break; 
 } 
 } 
}; 
class road_use : public vehicle { 
 int passengers; 
public: 
 road_use(int p, int w, int r) : vehicle(w, r) 
 { 
 passengers = p; 
 } 
 void showr() 
 { 
 cout << "Passengers: " << passengers << '\n'; 
 } 
}; 
enum steering { power, rack_pinion, manual }; 
Chương 6 Tính kế thừa 
200 
class car : public motorized, public road_use { 
 enum steering strng; 
public: 
 car(enum steering s, enum motor m, int w, int r, int p) : 
 road_use(p, w, r), motorized(m, w, r), vehicle(w, r) { 
 strng = s; 
 } 
 void show() { 
 showv(); showr(); showm(); 
 cout << "Steering: "; 
 switch(strng) { 
 case power : cout << "Power\n"; 
 break; 
 case rack_pinion : cout << "Rack and Pinion\n"; 
 break; 
 case manual : cout << "Manual\n"; 
 break; 
 } 
 } 
}; 
int main() 
{ 
 car c(power, gas, 4, 500, 5); 
 c.show(); 
 return 0; 
} 
Bài tập chương 6 
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 thoại. Cả hai lớp 
dẫn xuất đề có hàm tạo và hàm show. Viết chương trình thực hiện yêu cầu trên ? 
2. Cho đoạn chương trình sau, hãy bổ sung các chi tiết theo chỉ dẫn trong các lời chú 
giải 
#include 
class planet { 
protected: 
 double distance; // miles from the sun 
 int revolve; // in days 
public: 
 planet(double d, int r) { distance = d; revolve = r; } 
}; 
class earth : public planet { 
 double circumference; // circumference of orbit 
public: 
 // Create earth(double d, int r). Have it pass the distance and days of revolution 
back 
 // to planet. Have it compute the circumference of the orbit. 
 // (Hint : circumference = 2r*3.1416.) 
 // Create a function called show() that displays the information. 
}; 
int main() 
{ 
 earth ob(93000000, 365); 
 ob.show(); 
 return 0; 
} 
3. Cho đoạn chương trình sau, hãy bổ sung để chương trình chạy tốt 
Chương 6 Tính kế thừa 
202 
// Overload the +, -, and = relative to coord class. Then, use coord as a base for 
quad. 
#include 
class coord { 
public: 
 int x, y; // coordinate values 
 coord() { x=0; y=0; } 
 coord(int i, int j) { x=i; y=j; } 
 void get_xy(int &i, int &j) { i=x; j=y; } 
 coord operator+(coord ob2); 
 coord operator-(coord ob2); 
 coord operator=(coord ob2); 
}; 
// Overload + relative to coord class. 
coord coord::operator+(coord ob2) 
{ 
 coord temp; 
 cout << "Using coord operator+()\n"; 
 temp.x = x + ob2.x; 
 temp.y = y + ob2.y; 
 return temp; 
} 
// Overload - relative to coord class. 
coord coord::operator-(coord ob2) 
{ 
 coord temp; 
 cout << "Using coord operator-()\n"; 
 temp.x = x - ob2.x; 
 temp.y = y - ob2.y; 
 return temp; 
Chương 6 Tính kế thừa 
203 
} 
// Overload = relative to coord. 
coord coord::operator=(coord ob2) 
{ 
 cout << "Using coord operator=()\n"; 
 x = ob2.x; 
 y = ob2.y; 
 return *this; // return the object that is assigned to 
} 
class quad : public coord { 
 int quadrant; 
public: 
 quad() { x = 0; y = 0; quadrant = 0; } 
 quad(int x, int y) : coord(x, y) { 
 if(x>=0 && y>=0) quadrant = 1; 
 else if(x=0) quadrant = 2; 
 else if(x<0 && y<0) quadrant = 3; 
 else quadrant = 4; 
 } 
 void showq() { 
 cout << "Point in Quadrant: " << quadrant << '\n'; 
 } 
 quad operator=(coord ob2); 
}; 
quad quad::operator=(coord ob2) 
{ 
 cout << "Using quad operator=()\n"; 
 x = ob2.x; 
 y = ob2.y; 
Chương 6 Tính kế thừa 
204 
 if(x>=0 && y>=0) quadrant = 1; 
 else if(x=0) quadrant = 2; 
 else if(x<0 && y<0) quadrant = 3; 
else quadrant = 4; 
 return *this; 
} 
int main() 
{ 
 quad o1(10, 10), o2(15, 3), o3; 
 int x, y; 
 o3 = o1 + o2; // add two objects - this calls operator+() 
 o3.get_xy(x, y); 
 o3.showq(); 
 cout << "(o1+o2) X: " << x << ", Y: " << y << "\n"; 
 o3 = o1 - o2; // subtract two objects 
 o3.get_xy(x, y); 
 o3.showq(); 
 cout << "(o1-o2) X: " << x << ", Y: " << y << "\n"; 
 o3 = o1; // assign an object 
 o3.get_xy(x, y); 
 o3.showq(); 
 cout << "(o3=o1) X: " << x << ", Y: " << y << "\n"; 
 return 0; 
} 
4. Hãy sửa đổi chương trình trên sao cho nó sử dụng các hàm toán tử friend ? 
5. Hãy tạo một phân cấp lớp để lưu trữ thông tin về máy bay. Hãy bắt đầu bằng một 
lớp cơ sở tên là airship chứa thông tin về số lượng hành khách tối đa và trọng lượng 
hàng hoá tối đa (đơn vị tính là pound) mà máy bay có thể chở được. 
Chương 6 Tính kế thừa 
205 
Tạo hai lớp dẫn xuất airplane và balloons. Lớp airplane lưu kiểu của động cơ (gồm 
động cơ cánh quạt và động cơ phản lực), tầm xa (đơn vị tính là mile). Lớp balloon 
lưu thông tin về loại nhiên liệu sử dụng chi khí cầu (gồm hai loại là hydrogen và 
helium), độ cao tối đa (đơn vị tính là feed). Viết chương trình minh hoạ hoạt động 
của chúng. 

File đính kèm:

  • pdfbai_giang_lap_trinh_huong_doi_tuong_tap_1_chuong_6_tinh_ke_t.pdf