Bài giảng Kỹ thuật lập trình - Chương 10: Lập trình hướng đối tượng (Phần 2) - Lê Thành Sách
Nội dung
n Tại sao cần đến thừa kế
n Các khái niệm
n Thừa kế là gì?
n Các kiểu thừa kế
n Thiết kế các lớp (I).
n Khởi tạo lớp cha từ lớp con
n Thiết kế các lớp (II).
n Tổng kết
n Tại sao cần đến thừa kế
n Các khái niệm
n Thừa kế là gì?
n Các kiểu thừa kế
n Thiết kế các lớp (I).
n Khởi tạo lớp cha từ lớp con
n Thiết kế các lớp (II).
n Tổng kết
Bạn đang xem 20 trang mẫu của tài liệu "Bài giảng Kỹ thuật lập trình - Chương 10: Lập trình hướng đối tượng (Phần 2) - Lê Thành Sách", để tải tài liệu gốc về máy hãy click vào nút Download ở trên.
File đính kèm:
- bai_giang_ky_thuat_lap_trinh_chuong_10_lap_trinh_huong_doi_t.pdf
Nội dung text: Bài giảng Kỹ thuật lập trình - Chương 10: Lập trình hướng đối tượng (Phần 2) - Lê Thành Sách
- Nội dung n Tại sao cần đến thừa kế n Các khái niệm n Thừa kế là gì? n Các kiểu thừa kế n Thiết kế các lớp (I). n Khởi tạo lớp cha từ lớp con n Thiết kế các lớp (II). n Tổng kết Trường Đại Học Bách Khoa Tp.HCM Lập trình C/C++ Khoa Khoa học và Kỹ thuật Máy tính 2 © 2017
- Tại sao cần đến thừa kế n (1) Tạo chung một cấu trúc “User”, cấu trúc này có trường thông tin “type”. Giải thuật xử lý có dạng: switch (type){ case STUDENT:{ //Xử lý, nếu là sinh viên } case LECTURER:{ //Xử lý, nếu là giảng viên } }; Trường Đại Học Bách Khoa Tp.HCM Lập trình C/C++ Khoa Khoa học và Kỹ thuật Máy tính 4 © 2017
- Tại sao cần đến thừa kế n (2) Chia thành các nhóm nhỏ (lớp) nhỏ như: Student, Lecturer, Các phương thức xử lý gắn kèm với từng loại. class Student{ public: //Phương thức cho sinh viên }; class Lecturer{ public: //Phương thức cho giảng viên }; Trường Đại Học Bách Khoa Tp.HCM Lập trình C/C++ Khoa Khoa học và Kỹ thuật Máy tính 6 © 2017
- Tại sao cần đến thừa kế n (3) Sử dụng tính năng thừa kế (inheritance) n Chia tập lớn thành các lớp nhỏ (lớp nhỏ, như giải pháp số 2) n Với các lớp có quan hệ “is-a”, hãy khai báo thừa kế cho chúng n Tính năng thừa kế của ngôn ngữ lập trình (C++): n Các lớp con có thể thừa kế các thành viên từ lớp cha. n è Tránh được sự lặp lại code nói trên. n Các lớp cha có thể đại diện cho lớp con để xử lý một thông điệp (tính polymorphism) n è Dễ thiết kế + dễ thay đổi. Trường Đại Học Bách Khoa Tp.HCM Lập trình C/C++ Khoa Khoa học và Kỹ thuật Máy tính 8 © 2017
- Các khái niệm (I) Lý thuyết tập hợp Hướng đối tượng Thuật ngữ Tập cha Lớp cha Base class Parent class Super-class Tập con Lớp con Derived class Child-class Sub-class Trường Đại Học Bách Khoa Tp.HCM Lập trình C/C++ Khoa Khoa học và Kỹ thuật Máy tính 10 © 2017
- Các khái niệm (I) • Các lớp: Hình chữ nhật, trong đó có các thuộc tính và phương thức (nếu cần) • Quan hệ thừa kế: mũi tên từ lớp con đến lớp cha Trường Đại Học Bách Khoa Tp.HCM Lập trình C/C++ Khoa Khoa học và Kỹ thuật Máy tính 12 © 2017
- Thừa kế là gì?: Minh hoạ (I) class X{ Khai báo: public: Lớp Y thừa kế lớp X string sayHello(){ return "Hello"; Chú ý: dấu hai chấm “:” và } từ khoá public trước tên lớp }; cha class Y: public X{ } int main(){ Y obj; obj.sayHello(); return 0; } Trường Đại Học Bách Khoa Tp.HCM Lập trình C/C++ Khoa Khoa học và Kỹ thuật Máy tính 14 © 2017
- Thừa kế là gì?: Minh hoạ (II) (1) “name” là thuộc tính có tính private è ClassB không thừa kế được từ ClassA (2) Truy xuất đến “name” trong ClassB hay trong main (bên ngoài ClassA) à có lỗi biên dịch Trường Đại Học Bách Khoa Tp.HCM Lập trình C/C++ Khoa Khoa học và Kỹ thuật Máy tính 16 © 2017
- Thừa kế là gì?: Minh hoạ (III) (1) getName(): có tính public trong ClassA =>ClassB thừa kế được phương thức int main(){ này. ClassB obj; obj.setName("Nguyen Van An"); cout << obj.getName() << endl; return 0; } (2) getName(): trong ClassB là được thừa kế từ ClassA. Do từ khoá public trong dòng: class classB: public ClassA{ }; Nên getName() trong ClassB cũng có tính public à dùng được ở trong hàm “main” hay bất kỳ đâu. Trường Đại Học Bách Khoa Tp.HCM Lập trình C/C++ Khoa Khoa học và Kỹ thuật Máy tính 18 © 2017
- Thừa kế là gì?: Minh hoạ (IV) (1): “name” có tính protected trong ClassA è ClassB thừa kế được nó. (2): Do đó, truy cập “name” trong ClassB là không bị báo lỗi Trường Đại Học Bách Khoa Tp.HCM Lập trình C/C++ Khoa Khoa học và Kỹ thuật Máy tính 20 © 2017
- Các kiểu thừa kế Nếu ClassY thừa kế từ ClassX, thì có 3 dạng sau: class ClassY: public ClassX{ ß (phổ biến) }; class ClassY: protected ClassX{ }; class ClassY: private ClassX{ }; class ClassY: virtual public ClassX{ Và các dạng tương tự: trình bày trong phần “Bài }; toán kim cương” Trường Đại Học Bách Khoa Tp.HCM Lập trình C/C++ Khoa Khoa học và Kỹ thuật Máy tính 22 © 2017
- Các kiểu thừa kế n Thừa kế protected: class ClassY: protected ClassX{ }; n Các thành viên (thuộc tính + phương thức) có tính public và protected có trong ClassX đều có tính protected trong ClassY. n è Thành viên có tính public trong ClassX: sẽ không thể truy cập được từ đối tượng kiểu ClassY. n Lưu ý: ClassY không thể thừa kế các thành viên (thuộc tính + phương thức) có tính private từ ClassX Trường Đại Học Bách Khoa Tp.HCM Lập trình C/C++ Khoa Khoa học và Kỹ thuật Máy tính 24 © 2017
- Các kiểu thừa kế: Minh hoạ (I) è Cả setName() và getName(): Vẫn được nhìn thấy thông qua ClassA è Cả setName() và getName(): Không được nhìn thấy thông qua ClassB (vì ClassB thừa kế kiểu protected từ ClassA) Trường Đại Học Bách Khoa Tp.HCM Lập trình C/C++ Khoa Khoa học và Kỹ thuật Máy tính 26 © 2017
- Các kiểu thừa kế: Minh hoạ (II) class ClassA{ protected: string name; public: string getName(){ return this->name; } void setName(string name){ (1) Thừa kế kiểu private: this->name = name; è Cả setName() và getName(): } sẽ có tính private trong ClassB. }; class ClassB: private ClassA{ public: void print(){ cout getName() getName(): thừa kế từ ClassA. è Gọi được! Trường Đại Học BáchClassBKhoa Tp.HCMdùng được getName. Nhưng các lớp con của ClassB khôngLập dùng trình C/C++ Khoa Khoa học và Kỹ thuật Máy tính 28 © 2017 được getName được nữa – vì nó đã có tính private trong ClassB
- Thiết kế các lớp (I) class User{ }; class Student: public User{ }; class Staff: public User{ }; class Lecturer: public Staff{ }; class Clerk: public Staff{ }; Tương đương giữa code và sơ đồ class Guardian: public Staff{ }; class Cleaner: public Staff{ }; Trường Đại Học Bách Khoa Tp.HCM Lập trình C/C++ Khoa Khoa học và Kỹ thuật Máy tính 30 © 2017
- Thiết kế các lớp (I) User.h #ifndef USER_H Giúp tránh lỗi “tái định #define USER_H class User{ nghĩa” một khái niệm (redefinition); khái niệm ở }; #endif đây là lớp có tên “User” Student.h #ifndef STUDENT_H Từ “public” cho biết: #define STUDENT_H Lớp ”Student” không thay đổi tính khả kiến của các biến/hàm thành viên #include "User.h" trong lớp cha (User) class Student : public User{ }; #endif Dấu hai chấm “:” cho biết: Lớp “Student” thừa kế lớp “User” Trường Đại Học Bách Khoa Tp.HCM Lập trình C/C++ Khoa Khoa học và Kỹ thuật Máy tính 32 © 2017
- Thiết kế các lớp (I) User.h #ifndef USER_H Giúp tránh lỗi “tái định #define USER_H class User{ nghĩa” một khái niệm (redefinition); khái niệm ở }; #endif đây là lớp có tên “User” Staff.h #ifndef STAFF_H #define STAFF_H #include "User.h" class Staff: public User{ }; #endif Trường Đại Học Bách Khoa Tp.HCM Lập trình C/C++ Khoa Khoa học và Kỹ thuật Máy tính 34 © 2017
- Thiết kế các lớp (I) Sau khi sinh code, dự án có dạng: (chưa có *.cpp, các lớp đều rỗng) Trường Đại Học Bách Khoa Tp.HCM Lập trình C/C++ Khoa Khoa học và Kỹ thuật Máy tính 36 © 2017
- Thiết kế các lớp (III) Đa thừa kế: lớp ConsultantManager và PermanentManager, có đến 2 lớp cha. Trường hợp tổng quát: có thể có nhiều cha. Trường Đại Học Bách Khoa Tp.HCM Lập trình C/C++ Khoa Khoa học và Kỹ thuật Máy tính 38 © 2017
- Thiết kế các lớp: Bài tập 1 • Chuyển sang code C++ từ sơ đồ Trường Đại Học Bách Khoa Tp.HCM Lập trình C/C++ Khoa Khoa học và Kỹ thuật Máy tính 40 © 2017
- Thiết kế các lớp (IV) n Bài toán: n Xét bài toán về người dùng ở trường đại học - Xem: “Thiết kế các lớp (I)”. n Thực tế yêu cầu: n Mỗi người dùng điều có tên. n Lời giải: n Bổ sung một thuộc tính “name” vào đối tượng. Trường Đại Học Bách Khoa Tp.HCM Lập trình C/C++ Khoa Khoa học và Kỹ thuật Máy tính 42 © 2017
- Thiết kế các lớp (IV) Sơ đồ sau khi bổ sung thuộc tính + getter/setter • Biểu tượng ổ khoá đã khoá (-): private • Để trống (+): public • Biểu tượng chìa (#): protected Trường Đại Học Bách Khoa Tp.HCM Lập trình C/C++ Khoa Khoa học và Kỹ thuật Máy tính 44 © 2017
- Thiết kế các lớp (IV): code C++ User.cpp #include "User.h" std::string User::getUserName(void) { return userName; } void User::setUserName(std::string newUserName) { userName = newUserName; } “User::” dùng khi phương thức được định nghĩa bên ngoài phạm vi class (:: là toán tử phân giải tầm vực) Trường Đại Học Bách Khoa Tp.HCM Lập trình C/C++ Khoa Khoa học và Kỹ thuật Máy tính 46 © 2017
- Thiết kế các lớp (IV): code C++ Chương trình in ra kết quả sau: Lưu ý: Gọi setName() và getName() được, từ các đối tượng a,b, và c – vì: các lớp Student, Guardian, và Lecturer thừa kế chúng từ lớp User. Trường Đại Học Bách Khoa Tp.HCM Lập trình C/C++ Khoa Khoa học và Kỹ thuật Máy tính 48 © 2017
- Khởi tạo lớp cha từ lớp con Xét câu lệnh: Lecturer x; Câu hỏi: Vì vùng nhớ của x có gói luôn cả các đối tượng thuộc lớp cha của “Lecturer” là “Staff” và “User”, thứ tự tạo vùng nhớ này là như thế nào? Trả lời: Thự tự đó là a) Tạo đối tượng kiểu “User”, gọi hàm khởi tạo của User b) Tạo đối tượng kiểu “Staff”, gói đối tượng ở bước a) vào trong, và gọi hàm khởi tạo của “Staff”. c) Tạo đối tượng kiểu “Lecturer”, gói đối tượng ở bước b) vào trong, và gọi hàm khởi tạo của Lecturer. Trường Đại Học Bách Khoa Tp.HCM Lập trình C/C++ Khoa Khoa học và Kỹ thuật Máy tính 50 © 2017
- Khởi tạo lớp cha từ lớp con: Minh họa (I) #include using namespace std; class ClassX{ public: ClassX(){ cout << "Constructor of ClassX" << endl; }; }; class ClassY: public ClassX{ public: ClassY(){ cout << "Constructor of ClassY" << endl; }; }; class ClassZ: public ClassY{ public: ClassZ(){ cout << "Constructor of ClassZ" << endl; }; }; int main(){ ClassZ v; Dòng này in ra gì? return 0; } Trường Đại Học Bách Khoa Tp.HCM Lập trình C/C++ Khoa Khoa học và Kỹ thuật Máy tính 52 © 2017
- Khởi tạo lớp cha từ lớp con: Minh hoạ (II) #include using namespace std; class ClassX{ private: string name; public: ClassX(string name){ this->name = name; cout << "Constructor of ClassX" << endl; }; }; Khi ClassX có hàm khởi tạo cần đối số Trường Đại Học Bách Khoa Tp.HCM Lập trình C/C++ Khoa Khoa học và Kỹ thuật Máy tính 54 © 2017
- Khởi tạo lớp cha từ lớp con: Minh hoạ (III) class ClassT: public ClassY{ private: const int const_value; int ID; string str_value; public: ClassT(string name, string value): ClassY(name), const_value(100), str_value(value) { cout << "Constructor of ClassT" << endl; } }; Gọi hàm khởi tạo của lớp cha Khởi tạo biến thành viên Khởi tạo hằng (bắt buộc) Trường Đại Học Bách Khoa Tp.HCM Lập trình C/C++ Khoa Khoa học và Kỹ thuật Máy tính 56 © 2017
- Khởi tạo lớp cha từ lớp con: Minh hoạ (III) Trường Đại Học Bách Khoa Tp.HCM Lập trình C/C++ Khoa Khoa học và Kỹ thuật Máy tính 58 © 2017
- Định nghĩa lại phương thức: Minh hoạ class ClassA{ private: string name; public: ClassA(string name){ this->name = name; } string getName(){ return this->name; } void setName(string name){ this->name = name; } }; ClassA: có phương thức getName(): trả về dữ liệu “name” nó đang giữ Trường Đại Học Bách Khoa Tp.HCM Lập trình C/C++ Khoa Khoa học và Kỹ thuật Máy tính 60 © 2017
- Định nghĩa lại phương thức: Minh hoạ ClassA::getName(): //Need: #include gọi lại getName() trong lớp cha. class ClassB: public ClassA{ string getName(){ std::string str_temp = ClassA::getName(); std::transform(str_temp.begin(), str_temp.end(), str_temp.begin(), ::toupper); return str_temp; } }; Chuyển sang chữ hoa, dùng hàm transform. Trường Đại Học Bách Khoa Tp.HCM Lập trình C/C++ Khoa Khoa học và Kỹ thuật Máy tính 62 © 2017
- Định nghĩa lại phương thức: Minh hoạ (II) class ClassX{ public: void display(){ cout << "ClassX" << endl; } }; class ClassY: public ClassX{ public: void display(){ cout << "ClassY" << endl; } }; Định nghĩa lại phương thức “display” của lớp cha Trường Đại Học Bách Khoa Tp.HCM Lập trình C/C++ Khoa Khoa học và Kỹ thuật Máy tính 64 © 2017
- Định nghĩa lại phương thức: Minh hoạ (II) int main(){ ClassT obj; obj.ClassX::display(); obj.ClassY::display(); obj.ClassZ::display(); obj.ClassT::display(); return 0; } Đối tượng “obj” chứa bên trong các đối tượng của kiểu: ClassX, ClassY, ClassZ, và ClassT. Do đó, có đến 4 phương thức display. Trên đây là cách gọi từng phương thức trong đó. Kết quả in ra là gì? Trường Đại Học Bách Khoa Tp.HCM Lập trình C/C++ Khoa Khoa học và Kỹ thuật Máy tính 66 © 2017
- IDisplay + draw (Graphics g) : void > Shape Vector {abstract} - x : float - y : float + > getArea () : float + > Vector (float x, float y) + > fromPoints (Point from, Point to) : Vector + > isOrtho (Vector vector1, Vector vector2) : boolean TwoDShape + > TwoDShape () Point - x : float - y : float Polygon 0 1 0 * + > Point (float x, float y) vertexList + > getX () : float + > se tX (fl o a t n e wX ) : void + addVertex (Point vertex) : void + > getY () : float + getNumberOfVertices () : int + > se tY (fl o a t n e wY ) : void + > distanceAB (Point a, Point b) : float Rectangle + isValidRectangle () : boolean + getArea () : float Square Sử dụng ArrayList để lưu danh sách các đỉnh của Polygon: ArrayList vertexList Trường Đại Học Bách Khoa Tp.HCM Lập trình C/C++ Khoa Khoa+ > học và Kỹ thuậtSquare Máy () tính 68 + isValidSquare () : boolean © 2017
- IDisplay + draw (Graphics g) : void > Shape Vector {abstract} - x : float - y : float + > getArea () : float + > Vector (float x, float y) + > fromPoints (Point from, Point to) : Vector + > isOrtho (Vector vector1, Vector vector2) : boolean Ý nghĩa các phươngTwoDShape thức: + > TwoDShape () • fromPoints: tạo véc-tơ từ hai điểm (hàm Point có tính static) - x : float - y : float • isOrtho: kiểmPolygon tra xem hai véc-tơ có 0 1 0 * + > Point (float x, float y) vertexList + > getX () : float vuông góc (hàm có tính static) + > se tX (fl o a t n e wX ) : void + addVertex (Point vertex) : void + > getY () : float + getNumberOfVertices () : int • distanceAB: tính và trả về khoảng cách + > se tY (fl o a t n e wY ) : void giữa hai đỉnh (hàm có tính static) + > distanceAB (Point a, Point b) : float Rectangle + isValidRectangle () : boolean + getArea () : float Square Sử dụng ArrayList để lưu danh sách các đỉnh của Polygon: ArrayList vertexList Trường Đại Học Bách Khoa Tp.HCM Lập trình C/C++ Khoa Khoa+ > học và Kỹ thuậtSquare Máy () tính 70 + isValidSquare () : boolean © 2017
- Thiết kế các lớp (II): bài tập n Hãy thực hiện chuyển sang code C++ cho sơ đồ. n Bổ sung các hàm khởi tạo để giúp tạo đối tượng dễ dàng cho các kiểu, kể cả bổ sung hàm khởi tạo mặc nhiên và copy. n Bổ sung các toán tử cho các đối tượng n Viết chương trình dùng các đối tượng vừa tạo Trường Đại Học Bách Khoa Tp.HCM Lập trình C/C++ Khoa Khoa học và Kỹ thuật Máy tính 72 © 2017
- Tổng kết n Các điểm quan trọng vừa học n Định nghĩa lại phương thức của lớp cha + cách truy cập phương thức của lớp cha từ lớp con. n Biểu diễn bằng sơ đồ cho: n Các lớp n Quan hệ thừa kế (mũi tên) n Vận dụng thừa kế trong thiết kế phần mềm Trường Đại Học Bách Khoa Tp.HCM Lập trình C/C++ Khoa Khoa học và Kỹ thuật Máy tính 74 © 2017