Bài giảng Lập trình C++ 1 - Kế thừa
Bạn đang xem 20 trang mẫu của tài liệu "Bài giảng Lập trình C++ 1 - Kế thừa", để tải tài liệu gốc về máy bạn click vào nút DOWNLOAD ở trên
Tài liệu đính kèm:
bai_giang_lap_trinh_c_1_ke_thua.ppt
Nội dung text: Bài giảng Lập trình C++ 1 - Kế thừa
- Lập trình C++ 1 1
- Kế thừa 1. Quan hệ “has a” và “is a” 2. Bài toán minh hoạ composition 3. Kế thừa đơn 4. Nạp chồng 5. Từ khoá protected 6. Review 7. Bài tập 2
- Quan hệ “has a” và “is a” ⚫ Các đối tượng có thể có quan hệ với nhau. ⚫ Quan hệ “has a”: A “has a” B nếu trong đối tượng A có một thành phần là đối tượng B (quan hệ bao gồm - composition) ⚫ Ví dụ: Đối tượng Ngôi nhà có thành phần là đối tượng mái nhà, Tường và Cửa ra vào. Đối tượng Hình chữ nhật có thành phần là Điểm trên trái và dưới phải. Đối tượng Sinh viên có một thành phần là đối tượng Ngày tháng (ngày sinh) 3
- Quan hệ “has a” và “is a” ⚫ Quan hệ “is a”: A “is a” B nếu đối tượng A có những đặc tính của đối tượng B (quan hệ kế thừa - inheritance) ⚫ Ví dụ: Con voi có bản chất là một Động vật. Hình cầu là một sự mở rộng của Hình tròn. Sinh viên đại cương và Sinh viên chuyên ngành đều có những đặc điểm của Sinh viên ⚫ Chú ý: Trong lập trình đôi khi ta có thể cài đặt quan hệ giữa các đối tượng một cách “linh hoạt”. Chẳng hạn có thể coi Hình tròn là đối tượng chứa một Điểm (tâm hình tròn) hoặc là một sự kế thừa từ đối tượng Điểm (!?). 4
- Ví dụ minh hoạ composition ⚫ Xây dựng lớp Hinhchunhat từ lớp Diem ⚫ #include ⚫ // Lop Diem ⚫ class Diem ⚫ { ⚫ private: ⚫ int x, y; ⚫ public: ⚫ Diem(); // Cau tu mac dinh ⚫ Diem(int xx, int yy); // Cau tu khoi tao toa do ⚫ void DatToado(int xx, int yy); // Dat toa do ⚫ int LayX(); // Tra ve toa do x ⚫ int LayY(); // Tra ve toa do y ⚫ }; 5
- Ví dụ minh hoạ composition ⚫ // Cai dat phuong thuc ⚫ Diem::Diem() ⚫ { ⚫ DatToado(0, 0); ⚫ } ⚫ Diem::Diem(int xx, int yy) ⚫ { ⚫ DatToado(xx, yy); ⚫ } ⚫ void Diem::DatToado(int xx, int yy) ⚫ { ⚫ x = xx; ⚫ y = yy; ⚫ } ⚫ int Diem::LayX() { return x; } ⚫ int Diem::LayY() { return y; } 6
- Ví dụ minh hoạ composition ⚫ // Lop Hinhchunhat ⚫ class Hinhchunhat ⚫ { ⚫ private: Dữ liệu của Hinhchunhat gồm điểm trên trái và ⚫ Diem tt, dp; điểm dưới phải ⚫ public: ⚫ Hinhchunhat(); // Cau tu mac dinh ⚫ Hinhchunhat(int xtt, int ytt, int xdp, int ydp); // Khoi tao toa do ⚫ void HienThongtin(); // Hien thi thong tin ⚫ }; 7
- Ví dụ minh hoạ composition ⚫ Hinhchunhat::Hinhchunhat() : tt(0,0), dp(0,0) ⚫ { } ⚫ Hinhchunhat::Hinhchunhat(int xtt, int ytt, int xdp, int ydp) : ⚫ tt(xtt, ytt), dp(xdp, ydp) ⚫ { } Khởi tạo các đối tượng thành phần ⚫ void Hinhchunhat::HienThongtin() ⚫ { ⚫ cout<<"Toi la hinh chu nhat"<<endl; ⚫ cout<<"Toa do diem tren trai la:[“ ⚫ <<tt.LayX()<<","<<tt.LayY()<<"]"<<endl; ⚫ cout<<"Toa do diem duoi phai la: [“ ⚫ <<dp.LayX()<<","<<dp.LayY()<<"]"<<endl; ⚫ } 8
- Ví dụ minh hoạ composition ⚫ // main ⚫ void main() ⚫ { ⚫ Hinhchunhat hcna; ⚫ Hinhchunhat hcnb(1,1,20,10); ⚫ hcna.HienThongtin(); ⚫ hcnb.HienThongtin(); ⚫ } 9
- Ví dụ minh hoạ composition ⚫ Kết quả trên màn hình: ⚫ Toi la hinh chu nhat ⚫ Toa do diem tren trai la: [0,0] ⚫ Toa do diem duoi phai la: [0,0] ⚫ Toi la hinh chu nhat ⚫ Toa do diem tren trai la: [1,1] ⚫ Toa do diem duoi phai la: [20,10] 10
- Quan hệ composition ⚫ Chú ý: ⚫ Cấu tử của Diem sẽ được gọi trước cấu tử của Hinhchunhat ⚫ Huỷ tử của Hinhchunhat sẽ được gọi trước huỷ tử của Diem. ⚫ Nhận xét: ⚫ Quan hệ composition là rất “tự nhiên”. ⚫ Vì class Diem cũng là một kiểu dữ liệu (do người dùng tự định nghĩa) cho nên việc một đối tượng thuộc kiểu Diem có trong Hinhchunhat cũng giống như một dữ liệu kiểu int có trong một lớp nào đó. 11
- Kế thừa (Inheritance) ⚫ Kế thừa là một trong những đặc điểm quan trọng của OOP, nó cho phép xây dựng những lớp mới dựa trên những lớp đã có sẵn. ⚫ Lớp đã có sẵn gọi là lớp cơ sở (base class). ⚫ Lớp mới gọi là lớp dẫn xuất (derived class). Lớp cơ sở Lớp dẫn xuất 12
- Kế thừa (Inheritance) ⚫ Một số ví dụ về kế thừa: Hình tròn Sinh viên Động vật Hình cầu Sinh viên ĐC Đv trên cạn Đv dưới nước Sinh viên CN Con ếch Con cá 13
- Kế thừa đơn ⚫ Ví dụ: Xây dựng lớp Hinhcau kế thừa từ lớp Hinhtron ⚫ // lớp Hinhtron ⚫ class Hinhtron ⚫ { ⚫ private: ⚫ int bankinh; ⚫ public: ⚫ Hinhtron(); ⚫ Hinhtron(int bk); ⚫ void DatBankinh(int bk); ⚫ int LayBankinh(); ⚫ int LayDuongkinh(); ⚫ float LayDientich(); ⚫ }; ⚫ Giả sử các phương thức đã được định nghĩa 14
- Kế thừa đơn ⚫ // lớp Hinhcau ⚫ class Hinhcau : public Hinhtron ⚫ { ⚫ public: Lớp Hình cầu kế thừa dữ liệu ⚫ Hinhcau(); (bankinh) và các phương thức ⚫ Hinhcau(int bk); từ lớp Hình tròn. ⚫ float LayThetich(); ⚫ }; Lớp Hình cầu định nghĩa thêm các phương thức của riêng nó. 15
- Kế thừa đơn ⚫ Hinhcau::Hinhcau() : Hinhtron(0) ⚫ { Gọi cấu tử ⚫ } của lớp cha ⚫ Hinhcau::Hinhcau(int bk) : Hinhtron(bk) ⚫ { ⚫ } ⚫ float Hinhcau::LayThetich() ⚫ { Gọi phương thức của lớp cha ⚫ int r = LayBankinh(); ⚫ return float((float(4)/3)*3.14)*r*r*r; ⚫ } 16
- Kế thừa đơn ⚫ // test main 1 ⚫ void main() Gọi phương thức ⚫ { của lớp cha ⚫ Hinhcau hc; ⚫ hc.DatBankinh(3); ⚫ cout<<“Duong kinh hinh cau = “<<hc.LayDuongkinh(); ⚫ cout<<"The tich hinh cau = "<<hc.LayThetich(); ⚫ } Gọi phương thức đã định nghĩa thêm 17
- Kế thừa đơn ⚫ // test main 2 ⚫ void main() ⚫ { Gán đối tượng con cho ⚫ Hinhcau hc(3); đối tượng cha -> hợp lệ ⚫ Hinhtron ht = hc; ⚫ cout<<“Ban kinh hinh tron = "<<ht.LayBankinh(); ⚫ } ⚫ Chú ý về gán đối tượng: ⚫ Gán đối tượng con cho đối tượng cha chỉ đơn thuần là việc sao chép dữ liệu, đối tượng cha không thể sử dụng các phương thức của đối tượng con ⚫ Gán đối tượng cha cho đối tượng con là không hợp lệ 18
- Kế thừa đơn ⚫ Lớp con không kế thừa cấu tử và huỷ tử của lớp cha ⚫ Thứ tự gọi cấu tử và huỷ tử: ⚫ Cấu tử của lớp cha gọi trước rồi đến cấu tử lớp con ⚫ Huỷ tử của lớp con gọi trước rồi đến huỷ tử lớp cha 19
- Nạp chồng (overriding) ⚫ Làm thế nào để tính diện tích (bề mặt) của hình cầu ? Ta gọi hc.LayDientich() ? ⚫ Trả lời: hc.LayDientich sẽ trả lại giá trị diện tích của hình tròn -> kết quả không đúng ! ⚫ Giải pháp 1: Định nghĩa thêm một phương thức LayDientichHC trong lớp Hinhcau ⚫ Giải pháp 2: Định nghĩa nạp chồng (override) phương thức LayDientich trong lớp Hinhcau ⚫ Nạp chồng là việc định nghĩa lại một phương thức của lớp cha trong lớp con. 20
- Nạp chồng (overriding) ⚫ // lớp Hinhcau ⚫ class Hinhcau : public Hinhtron ⚫ { ⚫ public: Nạp chồng phương thức ⚫ LayDientich. ⚫ float LayDientich(); ⚫ }; ⚫ float Hinhcau::LayDientich() ⚫ { ⚫ int r = LayBankinh(); // phuong thuc LayBankinh la cua Hinhtron ⚫ return 4*3.14*r*r; ⚫ } 21
- Nạp chồng (overriding) ⚫ // test main 3 Vì đã nạp chồng LayDientich nên kết quả in ra sẽ là diện ⚫ void main() tích (bề mặt) của hình cầu. ⚫ { ⚫ Hinhcau hc(2); ⚫ cout<<“Dien tich hinh cau = "<<hc.LayDientich(); ⚫ } 22
- Toán tử phạm vi ⚫ Làm thế nào nếu ta muốn tính diện tích của mặt cắt qua tâm hình cầu (chính là diện tích hình tròn tương ứng) ? ⚫ Trả lời: Sử dụng toán tử phạm vi :: ⚫ // test main 4 ⚫ void main() ⚫ { ⚫ Hinhcau hc(2); ⚫ cout<<“Dien tich hinh cau = "<<hc.LayDientich(); ⚫ cout<<“Dien tich mat cat = "<<hc.Hinhtron::LayDientich(); ⚫ } 23
- Từ khoá protected ⚫ Trong phương thức LayDientich và LayThetich của lớp Hinhcau, để lấy lại giá trị bán kính ta phải dùng LayBankinh() vì bankinh được khai báo là private. ⚫ Nếu khai báo bankinh là public thì sẽ vi phạm tính che dấu dữ liệu. ⚫ -> Giải pháp: Dùng từ khoá protected ⚫ Từ khoá protected cho phép dữ liệu/phương thức của lớp cha có thể được truy nhập từ lớp con (mà không được truy nhập từ các lớp khác). 24
- Từ khoá protected ⚫ // lớp Hinhtron ⚫ class Hinhtron bankinh sẽ có thể ⚫ { được truy nhập từ lớp ⚫ protected: con của Hinhtron ⚫ int bankinh; ⚫ public: ⚫ ⚫ }; ⚫ float Hinhcau::LayThetich() ⚫ { return (float(4)/3)*3.14*bankinh*bankinh*bankinh; } ⚫ float Hinhcau::LayDientich() ⚫ { return 4*3.14*bankinh*bankinh; } 25
- Đặc điểm của OOP (đặc điểm 2) ⚫ Tính kế thừa (inheritance) ⚫ OOP cho phép xây dựng các lớp mới từ những lớp có sẵn-lớp cơ sở và cho phép lớp mới nạp chồng các phương thức của lớp cơ sở. ⚫ Tính kế thừa cho phép lập trình viên sử dụng lại những đoạn mã có sẵn, tránh việc phát minh lại chiếc bánh xe (reinvent the wheel). 26
- Các kiểu kế thừa ⚫ Lớp B có thể kế thừa từ lớp A theo 3 kiểu là public, private và protected. ⚫ class Hinhcau : public Hinhtron ⚫ class Hinhcau : private Hinhtron ⚫ class Hinhcau : protected Hinhtron ⚫ Chi tiết về các kiểu kế thừa được nghiên cứu trong bài 5. 27
- Review 1. Phân biệt quan hệ “has a” và “is a” ? 2. Kế thừa trong OOP là gì ? 3. Nạp chồng (overiding) là gì ? 4. Đối tượng của lớp dẫn xuất có phải là đối tượng của lớp cơ sở không ? (và ngược lại) 5. Trong quá trình tạo và huỷ đối tượng, cấu tử và huỷ tử của lớp cơ sở và lớp dẫn xuất được gọi thế nào ? 6. Từ khoá protected dùng để làm gì ? 28
- Bài tập về nhà 1. Cài đặt đầy đủ lớp Điểm và lớp Hinhchunhat. Thêm cấu tử khởi tạo Hinhchunhat từ hai điểm và cấu tử sao chép. Thêm phương thức tính giao của 2 hình chữ nhật, kiểm tra một điểm có nằm trong hình chữ nhật hay không (quá tải phương thức này). Viết chương trình nhập một hình chữ nhật, sau đó phát sinh 100 điểm ngẫu nhiên và cho biết có bao nhiêu điểm nằm trong hình chữ nhật đã nhập. Viết chương trình nhập vào 3 hình chữ nhật và tính giao đôi một của các hình này. 29
- Bài tập về nhà 2. Tạo lớp Hinhtru kế thừa từ lớp Hinhtron, lớp này có thêm dữ liệu là độ cao. Nạp chồng và định nghĩa thêm các phương thức cần thiết. 3. Xây dựng lớp Animal có dữ liệu là tên và các phương thức cơ bản. Thêm phương thức Speak(). Xây dựng lớp Dog, Cat kế thừa từ Animal. Nạp chồng Speak(). 30