Bài giảng Lập trình C/C++ - Chương 10: Lập trình hướng đối tượng (Thừa kế) - Lê Thành Sách

Nội dung

 Tại sao cần đến thừa kế

 Các khái niệm

 Thừa kế là gì?

 Các kiểu thừa kế

Thiết kế các lớp (I).

 Khởi tạo lớp cha từ lớp con

 Thiết kế các lớp (II).

 Tổng kết

pdf 74 trang phuongnguyen 2980
Bạn đang xem 20 trang mẫu của tài liệu "Bài giảng Lập trình C/C++ - Chương 10: Lập trình hướng đối tượng (Thừa kế) - 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

Tóm tắt nội dung tài liệu: Bài giảng Lập trình C/C++ - Chương 10: Lập trình hướng đối tượng (Thừa kế) - Lê Thành Sách

Bài giảng Lập trình C/C++ - Chương 10: Lập trình hướng đối tượng (Thừa kế) - Lê Thành Sách
Trường Đại Học Bách Khoa Tp.HCM
Khoa Khoa học và Kỹ thuật Máy tính
© 2017
Lập trình C/C++
1
Chương 10
Lập trình hướng đối tượng
--Thừa kế--
Lê Thành Sách
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa Tp.HCM
Khoa Khoa học và Kỹ thuật Máy tính
© 2017
Lập trình C/C++
2
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
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa Tp.HCM
Khoa Khoa học và Kỹ thuật Máy tính
© 2017
Lập trình C/C++
3
Tại sao cần đến thừa kế
n Giả sử một hệ thống phần mềm cho một trường đại học 
(Bách Khoa). Nhiều nhóm người dùng có thể dùng hệ 
thống này, họ có thể là:
a) Giảng viên (lecturer)
b) Sinh viên (student)
c) Nhân viên văn phòng (clerk)
d) Bảo vệ (guardian)
e) Người dọn dẹp (cleaner)
f) v.v
n Mỗi nhóm người dùng có những tính năng khác nhau, hệ 
thống xử lý dữ liệu với từng nhóm cũng khác nhau. 
n Giải pháp là gì để phầm mềm xử lý dữ liệu với từng nhóm 
người theo cách khác nhau?
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa Tp.HCM
Khoa Khoa học và Kỹ thuật Máy tính
© 2017
Lập trình C/C++
4
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
}
...
};
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa Tp.HCM
Khoa Khoa học và Kỹ thuật Máy tính
© 2017
Lập trình C/C++
5
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:
n Nhược điểm:
n Code dài dòng
n Khó thay đổi
n Khó mở rộng
n 
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa Tp.HCM
Khoa Khoa học và Kỹ thuật Máy tính
© 2017
Lập trình C/C++
6
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
};
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa Tp.HCM
Khoa Khoa học và Kỹ thuật Máy tính
© 2017
Lập trình C/C++
7
Tại sao cần đến thừa kế
n (2) Chia thành các nhóm (lớp) nhỏ như: Student, Lecturer, 
 Các phương thức xử lý gắn kèm với từng loại.
n Nhược điểm:
n Lặp lại code (code duplication)
n Ví dụ: 
n Phương thức “getName”/”setName” (lấy/gán tên) đều 
phải hiện thực lại cho tất cả các lớp.
n Khó bảo trì
n Khó thay đổi hay nâng cấp
n 
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa Tp.HCM
Khoa Khoa học và Kỹ thuật Máy tính
© 2017
Lập trình C/C++
8
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.
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa Tp.HCM
Khoa Khoa học và Kỹ thuật Máy tính
© 2017
Lập trình C/C++
9
Các khái niệm (I)
User
Student
Staff
Guardian
Accountant
Lecturer
Cleaner
Chia nhỏ tập hợp “User” thành các tập hợp con
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa Tp.HCM
Khoa Khoa học và Kỹ thuật Máy tính
© 2017
Lập trình C/C++
10
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
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa Tp.HCM
Khoa Khoa học và Kỹ thuật Máy tính
© 2017
Lập trình C/C++
11
Các khái niệm (I)
User
Student
Staff
Guardian
Accountant
Lecturer
Cleaner
Mô hình cây tương ứng
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa Tp.HCM
Khoa Khoa học và Kỹ thuật Máy tính
© 2017
Lập trình C/C++
12
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
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa Tp.HCM
Khoa Khoa học và Kỹ thuật Máy tính
© 2017
Lập trình C/C++
13
Thừa kế là gì?
n Là một tính chất cho biết:
n Một lớp con thể thừa hưởng các thành viên (thuộc tính + phương 
thức) có tính public và protected trong lớp cha.
n Không thừa hưởng thành viên có tính private.
n Cũng có nghĩa,
n Lớp con không khai báo nhưng vẫn có các thành viên public và 
protected của lớp cha.
n Với phương thức: có thể thừa kế và thay đổi nội dung của 
phương thức (xem: Phần định nghĩa phương thức - Overriding)
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa Tp.HCM
Khoa Khoa học và Kỹ thuật Máy tính
© 2017
Lập trình C/C++
14
Thừa kế là gì?: Minh hoạ (I)
class X{
public:
string sayHello(){
return "Hello";
}
};
class Y: public X{
}
int main(){
Y obj;
obj.sayHello();
return 0;
}
Khai báo: 
Lớp Y thừa kế lớp X
Chú ý: dấu hai chấm “:” và 
từ khoá public trước tên lớp 
cha
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa Tp.HCM
Khoa Khoa học và Kỹ thuật Máy tính
© 2017
Lập trình C/C++
15
Thừa kế là gì?: Minh hoạ (I)
class X{
public:
string sayHello(){
return "Hello";
}
};
class Y: public X{
}
int main(){
Y obj;
obj.sayHello();
return 0;
}
sayHello: được gọi với đối 
tượng obj, kiểu Y.
Trong phần mô tả của lớp Y, 
không có sayHello.
Nhưng, lớp Y thừa kế 
sayHello (public) của lớp X. 
Do đó, biên dịch thành công 
và chạy được.
Xuất ra màn hình:
Hello
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa Tp.HCM
Khoa Khoa học và Kỹ thuật Máy tính
© 2017
Lập trình C/C++
16
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
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa Tp.HCM
Khoa Khoa học và Kỹ thuật Máy tính
© 2017
Lập trình C/C++
17
Thừa kế là gì?: Minh hoạ (III)
class ClassA{
private:
string name;
public:
string getName(){
return this->name;
}
void setName(string name){
this->name = name;
}
};
class ClassB: public ClassA{
public:
void print(){
cout getName() << endl;
}
};
(1) getName(): có tính public trong ClassA 
=>ClassB thừa kế được phương thức 
này.
(2) getName(): có thể dùng được trong các 
phương thức của ClassB
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa Tp.HCM
Khoa Khoa học và Kỹ thuật Máy tính
© 2017
Lập trình C/C++
18
Thừa kế là gì?: Minh hoạ (III)
int main(){
ClassB obj;
obj.setName("Nguyen Van An");
cout << obj.getName() << endl;
return 0;
}
(1) getName(): có tính public trong ClassA 
=>ClassB thừa kế được phương thức 
này.
(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.
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa Tp.HCM
Khoa Khoa học và Kỹ thuật Máy tính
© 2017
Lập trình C/C++
19
Thừa kế là gì?: Minh hoạ (III)
int main(){
ClassB obj;
obj.setName("Nguyen Van An");
cout << obj.getName() << endl;
return 0;
}
(1) getName(): có tính public trong ClassA 
=>ClassB thừa kế được phương thức 
này.
(3) Dòng này sẽ bị báo lỗi nếu thay từ public trong dòng sau 
thành: protected hay private - Xem “các kiểu thừa kế”.
class classB: public ClassA{ };
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa Tp.HCM
Khoa Khoa học và Kỹ thuật Máy tính
© 2017
Lập trình C/C++
20
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
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa Tp.HCM
Khoa Khoa học và Kỹ thuật Máy tính
© 2017
Lập trình C/C++
21
Thừa kế là gì?: Minh hoạ (IV)
(3): Trên dòng 212, khai kháo thừa kế 
có tính publicè “name” trong ClassB 
vẫn có tính protected như trong ClassA
(Xem: các kiểu thừa kế).
è Truy cập “name” bên ngoài classB là 
có lỗi.
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa Tp.HCM
Khoa Khoa học và Kỹ thuật Máy tính
© 2017
Lập trình C/C++
22
Các kiểu thừa kế
class ClassY: public ClassX{
};
class ClassY: protected ClassX{
};
class ClassY: private ClassX{
};
Nếu ClassY thừa kế từ ClassX, thì có 3 dạng sau:
ß (phổ biến)
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”
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa Tp.HCM
Khoa Khoa học và Kỹ thuật Máy tính
© 2017
Lập trình C/C++
23
Các kiểu thừa kế
n Thừa kế public:
n Các thành viên (thuộc tính + phương thức) có tính public và 
protected có trong ClassX vẫn giữa nguyên tính khả kiến của nó 
trong ClassY.
n Đây là dạng phổ biến nhất trong 3 dạng
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
class ClassY: public ClassX{
};
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa Tp.HCM
Khoa Khoa học và Kỹ thuật Máy tính
© 2017
Lập trình C/C++
24
Các kiểu thừa kế
n Thừa kế protected:
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
class ClassY: protected ClassX{
};
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa Tp.HCM
Khoa Khoa học và Kỹ thuật Máy tính
© 2017
Lập trình C/C++
25
Các kiểu thừa kế: Minh hoạ (I)
class ClassA{
protected:
string name;
public:
string getName(){
return this->name;
}
void setName(string name){
this->name = name;
}
};
class ClassB: protected ClassA{
public:
void print(){
cout getName() << endl;
}
};
(1) Thừa kế kiểu protected:
è Cả setName() và getName(): 
sẽ có tính protected trong ClassB.
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa Tp.HCM
Khoa Khoa học và Kỹ thuật Máy tính
© 2017
Lập trình C/C++
26
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)
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa Tp.HCM
Khoa Khoa học và Kỹ thuật Máy tính
© 2017
Lập trình C/C++
27
Các kiểu thừa kế
n Thừa kế private:
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 private 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
class ClassY: private ClassX{
};
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa Tp.HCM
Khoa Khoa học và Kỹ thuật Máy tính
© 2017
Lập trình C/C++
28
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){
this->name = name;
}
};
class ClassB: private ClassA{
public:
void print(){
cout getName() << endl;
}
};
(1) Thừa kế kiểu private:
è Cả setName() và getName(): 
sẽ có tính private trong ClassB.
this->getName(): thừa kế từ ClassA.
è Gọi được!
ClassB dùng được getName. Nhưng các lớp con của ClassB không dùng
được getName được nữa – vì nó đã có tính private trong ClassBCuuDuon ThanCong.co https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa Tp.HCM
Khoa Khoa học và Kỹ thuật Máy tính
© 2017
Lập trình C/C++
29
Các kiểu thừa kế: Minh hoạ (II)
è 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 private từ ClassA)
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa Tp.HCM
Khoa Khoa học và Kỹ thuật Máy tính
© 2017
Lập trình C/C++
30
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{
};
class Guardian: public Staff{
};
class Cleaner: public Staff{
};
Tương đương giữa code và sơ đồ
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa Tp.HCM
Khoa Khoa học và Kỹ thuật Máy tính
© 2017
Lập trình C/C++
31
Thiết kế các lớp (I)
Nếu tách riêng phần khai báo và phần định nghĩa vào hai 
tập tin: *.h và *.cpp
Xem kết quả sau.
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa Tp.HCM
Khoa Khoa học và Kỹ thuật Máy tính
© 2017
Lập trình C/C++
32
Thiết kế các lớp (I)
#ifndef USER_H
#define USER_H
class User{
};
#endif
#ifndef STUDENT_H
#define STUDENT_H
#include "User.h"
class Student : public User{
};
#endif
Giúp tránh lỗi “tái định 
nghĩa” một khái niệm 
(redefinition); khái niệm ở 
đây là lớp có tên “User”
Dấu hai chấm “:” cho biết:
Lớp “Student” thừa kế lớp “User”
Từ “public” cho biết: 
Lớp ”Student” không thay đổi tính 
khả kiến của các biến/hàm thành viên 
trong lớp cha (User)
User.h
Student.h
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa Tp.HCM
Khoa Khoa học và Kỹ thuật Máy tính
© 2017
Lập trình C/C++
33
Thiết kế các lớp (I)
#ifndef USER_H
#define USER_H
class User{
};
#endif
#ifndef STUDENT_H
#define STUDENT_H
#include "User.h"
class Student : public User{
};
#endif
Giúp tránh lỗi “tái định 
nghĩa” một khái niệm 
(redefinition); khái niệm ở 
đây là lớp có tên “User”
Phải chèn “header” file của lớp cha tại 
đây để bộ biên dịch biết được danh hiệu 
“User” là gì.
Nếu không, có lỗi “undefined data-type”
User.h
Student.h
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa Tp.HCM
Khoa Khoa học và Kỹ thuật Máy tính
© 2017
Lập trình C/C++
34
Thiết kế các l ...  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.
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa Tp.HCM
Khoa Khoa học và Kỹ thuật Máy tính
© 2017
Lập trình C/C++
51
Khởi tạo lớp cha từ lớp con: Minh hoạ (I)
ClassX
ClassY
ClassZ
is-a
is-a
Đối tượng của ClassZ
Đối tượng của ClassY
Đối tượng của ClassX
Cây thừa kế
Chỉ 01 dòng lệnh:
ClassZ v;
Đã tạo ra một đối tượng kiểu ClassZ, 
gói trong đó cả đối tượng của ClassY 
và ClassX
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa Tp.HCM
Khoa Khoa học và Kỹ thuật Máy tính
© 2017
Lập trình C/C++
52
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;
return 0;
}
Dòng này in ra gì?
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa Tp.HCM
Khoa Khoa học và Kỹ thuật Máy tính
© 2017
Lập trình C/C++
53
Khởi tạo lớp cha từ lớp con: Minh hoạ (I)
Chương trình xuất ra theo thứ tự gọi hàm khởi tạo 
cho ClassX, ClassY, cuối cùng là cho ClassZ
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa Tp.HCM
Khoa Khoa học và Kỹ thuật Máy tính
© 2017
Lập trình C/C++
54
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ố
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa Tp.HCM
Khoa Khoa học và Kỹ thuật Máy tính
© 2017
Lập trình C/C++
55
Khởi tạo lớp cha từ lớp con: Minh hoạ (II)
class ClassY: public ClassX{
public:
ClassY(string name): ClassX(name){ 
cout << "Constructor of ClassY" << endl; 
};
};
class ClassZ: public ClassY{
public:
ClassZ(string name): ClassY(name){ 
cout << "Constructor of ClassZ" << endl; 
};
};
int main(){
ClassZ v(“Nguyen Ngoc An”);
return 0;
}
Cách gọi hàm khởi tạo của lớp cha, 
từ hàm khởi tạo của lớp con.
Chú ý:
• Dấu hai chấm “:”
• Và, vị trí là đứng liền trước thân 
hàm khởi tạo
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa Tp.HCM
Khoa Khoa học và Kỹ thuật Máy tính
© 2017
Lập trình C/C++
56
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 hằng (bắt buộc)
Khởi tạo biến thành viên
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa Tp.HCM
Khoa Khoa học và Kỹ thuật Máy tính
© 2017
Lập trình C/C++
57
Khởi tạo lớp cha từ lớp con: Bài tập
n Bổ sung mã nguồn để cho phép người lập trình có thể 
truyền tên của người dùng vào hàm khởi tạo của tất cả các 
nhóm người dùng, như ví dụ:
n Gợi ý:
n Xem hình vẽ sau
n Sử dụng cách khởi động như trong trước
Student a("Nguyen Ngoc Anh");
Guardian b("Le Van Bao");
Lecturer c("Nguyen Minh Phuong");
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa Tp.HCM
Khoa Khoa học và Kỹ thuật Máy tính
© 2017
Lập trình C/C++
58
Khởi tạo lớp cha từ lớp con: Minh hoạ (III)
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa Tp.HCM
Khoa Khoa học và Kỹ thuật Máy tính
© 2017
Lập trình C/C++
59
Định nghĩa lại phương thức (Overriding)
n Overriding là gì?
n Là khả năng mà một lớp con có thể định nghĩa lại (override) những 
phương thức mà nó thừa kế được từ lớp cha
n Định nghĩa lại để làm gì?
n Để phản ánh dữ liệu mà nó đang giữ
n Để phù hợp hơn với kiểu hiện tại
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa Tp.HCM
Khoa Khoa học và Kỹ thuật Máy tính
© 2017
Lập trình C/C++
60
Đị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ữ
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa Tp.HCM
Khoa Khoa học và Kỹ thuật Máy tính
© 2017
Lập trình C/C++
61
Định nghĩa lại phương thức: Minh hoạ
//Need: #include 
class ClassB: public ClassA{
public:
ClassB(string name): ClassA(name){
}
string getName(){
std::string str_temp = ClassA::getName();
std::transform(str_temp.begin(),
str_temp.end(),
str_temp.begin(),
::toupper);
return str_temp;
}
}; ClassB thừa kế ClassA: 
• Đã có sẵn getName():
• Nhưng ClassB muốn tên được trả về phải được chuẩn hoá (đổi 
sang chữ HOA)
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa Tp.HCM
Khoa Khoa học và Kỹ thuật Máy tính
© 2017
Lập trình C/C++
62
Định nghĩa lại phương thức: Minh hoạ
//Need: #include 
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;
}
};
ClassA::getName(): 
gọi lại getName() trong lớp cha.
Chuyển sang chữ hoa, dùng hàm 
transform.
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa Tp.HCM
Khoa Khoa học và Kỹ thuật Máy tính
© 2017
Lập trình C/C++
63
Định nghĩa lại phương thức: Minh hoạ
int main(){
ClassB obj("nguyen van an");
cout << obj.ClassA::getName() << endl;
cout << obj.getName() << endl;
return 0;
}
Trong đối tượng obj: có hai phương thức 
getName(): một cho đối tượng từ lớp cha 
(ClassA), và một cho classB.
Cách này dùng để gọi getName() cho 
lớp ClassA à in ra chữ thường
Kết quả in ra màn hình:
Gọi getName() của 
ClassB à in ra chữ HOA.
Xem kết quả sau:
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa Tp.HCM
Khoa Khoa học và Kỹ thuật Máy tính
© 2017
Lập trình C/C++
64
Đị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
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa Tp.HCM
Khoa Khoa học và Kỹ thuật Máy tính
© 2017
Lập trình C/C++
65
Định nghĩa lại phương thức: Minh hoạ (II)
Định nghĩa lại phương thức “display” của lớp cha
class ClassZ: public ClassY{
public:
void display(){
cout << "ClassZ" << endl;
}
};
class ClassT: public ClassZ{
public:
void display(){
cout << "ClassT" << endl;
}
};
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa Tp.HCM
Khoa Khoa học và Kỹ thuật Máy tính
© 2017
Lập trình C/C++
66
Định nghĩa lại phương thức: Minh hoạ (II)
Đố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ì?
int main(){
ClassT obj;
obj.ClassX::display();
obj.ClassY::display();
obj.ClassZ::display();
obj.ClassT::display();
return 0;
}
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa Tp.HCM
Khoa Khoa học và Kỹ thuật Máy tính
© 2017
Lập trình C/C++
67
Thiết kế các lớp (II)
n Bài toán:
n Viết chương trình cho phép vẽ các đối tượng hình học 2D đơn giản:
n a) Hình Chữ nhật
n b) Hình vuông
n c) Hình đa giác
n d) Điểm
n c) Véc-tơ
n Câu hỏi:
n Nên có những lớp gì? Quan hệ ra sao trong bài toàn này?
n Xem bản thiết kế sau.
n Trong đó có hai khái niệm chưa giải thích, đến thời điểm này:
n Interface
n Virtual Method + Abstract method
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa Tp.HCM
Khoa Khoa học và Kỹ thuật Máy tính
© 2017
Lập trình C/C++
68
Sử dụng ArrayList để lưu danh sách các đỉnh của Polygon:
ArrayList vertexList
0..1 0..*
vertexList
>
Shape
{abstract}
+ > getArea () : float
TwoDShape
+ > TwoDShape ()
Polygon
+
+
addVertex (Point vertex)
getNumberOfVertices ()
: void
: int
Rectangle
+
+
isValidRectangle ()
getArea ()
: boolean
: float
Square
+
+
> Square ()
isValidSquare () : boolean
Point
-
-
x
y
: float
: float
+
+
+
+
+
+
>
>
>
>
>
>
Point (float x, float y)
getX ()
setX (float newX)
getY ()
setY (float newY)
distanceAB (Point a, Point b)
: float
: void
: float
: void
: float
IDisplay
+ draw (Graphics g) : void
Vector
-
-
x
y
: float
: float
+
+
+
>
>
>
Vector (float x, float y)
fromPoints (Point from, Point to)
isOrtho (Vector vector1, Vector vector2)
: Vector
: boolean
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa Tp.HCM
Khoa Khoa học và Kỹ thuật Máy tính
© 2017
Lập trình C/C++
69
Sử dụng ArrayList để lưu danh sách các đỉnh của Polygon:
ArrayList vertexList
0..1 0..*
vertexList
>
Shape
{abstract}
+ > getArea () : float
TwoDShape
+ > TwoDShape ()
Polygon
+
+
addVertex (Point vertex)
getNumberOfVertices ()
: void
: int
Rectangle
+
+
isValidRectangle ()
getArea ()
: boolean
: float
Square
+
+
> Square ()
isValidSquare () : boolean
Point
-
-
x
y
: float
: float
+
+
+
+
+
+
>
>
>
>
>
>
Point (float x, float y)
getX ()
setX (float newX)
getY ()
setY (float newY)
distanceAB (Point a, Point b)
: float
: void
: float
: void
: float
IDisplay
+ draw (Graphics g) : void
Vector
-
-
x
y
: float
: float
+
+
+
>
>
>
Vector (float x, float y)
fromPoints (Point from, Point to)
isOrtho (Vector vector1, Vector vector2)
: Vector
: boolean
Một đối tượng kiểu Polygon (đa giác) có thể có chứa kèm một danh sách gồm nhiều đối 
tượng kiểu Point, danh sách có thể trống.
Ngược lại: Một đối tượng kiểu Point, có thể chứa hoặc không chứa kèm một đối tượng 
kiểu Polygon .
“Chứa” là gì?
• Hoặc chứa trực tiếp đối tượng bên trong (composition)
• Hoặc chỉ chứa con trỏ đến đối tượng cần chứa (aggregation)
-------
Cụ thể: Danh sách mà Polygon chứa ở đây chính là danh sách các đỉnh của Polygon
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa Tp.HCM
Khoa Khoa học và Kỹ thuật Máy tính
© 2017
Lập trình C/C++
70
Sử dụng ArrayList để lưu danh sách các đỉnh của Polygon:
ArrayList vertexList
0..1 0..*
vertexList
>
Shape
{abstract}
+ > getArea () : float
TwoDShape
+ > TwoDShape ()
Polygon
+
+
addVertex (Point vertex)
getNumberOfVertices ()
: void
: int
Rectangle
+
+
isValidRectangle ()
getArea ()
: boolean
: float
Square
+
+
> Square ()
isValidSquare () : boolean
Point
-
-
x
y
: float
: float
+
+
+
+
+
+
>
>
>
>
>
>
Point (float x, float y)
getX ()
setX (float newX)
getY ()
setY (float newY)
distanceAB (Point a, Point b)
: float
: void
: float
: void
: float
IDisplay
+ draw (Graphics g) : void
Vector
-
-
x
y
: float
: float
+
+
+
>
>
>
Vector (float x, float y)
fromPoints (Point from, Point to)
isOrtho (Vector vector1, Vector vector2)
: Vector
: boolean
Ý nghĩa các phương thức:
• fromPoints: tạo véc-tơ từ hai điểm (hàm 
có tính static)
• isOrtho: kiểm tra xem hai véc-tơ có 
vuông góc (hàm có tính static)
• distanceAB: tính và trả về khoảng cách 
giữa hai đỉnh (hàm có tính static)
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa Tp.HCM
Khoa Khoa học và Kỹ thuật Máy tính
© 2017
Lập trình C/C++
71
Sử dụng ArrayList để lưu danh sách các đỉnh của Polygon:
ArrayList vertexList
0..1 0..*
vertexList
>
Shape
{abstract}
+ > getArea () : float
TwoDShape
+ > TwoDShape ()
Polygon
+
+
addVertex (Point vertex)
getNumberOfVertices ()
: void
: int
Rectangle
+
+
isValidRectangle ()
getArea ()
: boolean
: float
Square
+
+
> Square ()
isValidSquare () : boolean
Point
-
-
x
y
: float
: float
+
+
+
+
+
+
>
>
>
>
>
>
Point (float x, float y)
getX ()
setX (float newX)
getY ()
setY (float newY)
distanceAB (Point a, Point b)
: float
: void
: float
: void
: float
IDisplay
+ draw (Graphics g) : void
Vector
-
-
x
y
: float
: float
+
+
+
>
>
>
Vector (float x, float y)
fromPoints (Point from, Point to)
isOrtho (Vector vector1, Vector vector2)
: Vector
: boolean
Dùng quan hệ thừa kế (C++)
Ý nghĩa các phương thức:
• getArea: tính và trả về diện tích hình 2D.
• addVertex: thêm một đỉnh vào đối tượng 
Polygon
• getNumberOfVertices: trả về số lượng đỉnh
• isValidRectangle: kiểm xem da h sách đỉnh 
có tạo thành hình chữ nhật
• isValidSquare: kiểm xem da h sách đỉnh có 
tạo thành hình vuông
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa Tp.HCM
Khoa Khoa học và Kỹ thuật Máy tính
© 2017
Lập trình C/C++
72
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
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa Tp.HCM
Khoa Khoa học và Kỹ thuật Máy tính
© 2017
Lập trình C/C++
73
Tổng kết
n Các điểm quan trọng vừa học
n Tại sao cần thừa kế
n Hiểu rõ ý nghĩa thực sự của thừa kế
n Tính khả kiến (public, protected, và private) tác động gì đến sự thừa 
kế
n Có thừa kế được thành viên có tính private?
n Thừa kế kiểu: public, protected, và private là gì
n Khởi tạo lớp cha từ lớp con.
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa Tp.HCM
Khoa Khoa học và Kỹ thuật Máy tính
© 2017
Lập trình C/C++
74
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
CuuDuongThanCong.com https://fb.com/tailieudientucntt

File đính kèm:

  • pdfbai_giang_lap_trinh_cc_chuong_10_lap_trinh_huong_doi_tuong_t.pdf