Professional Documents
Culture Documents
LTHĐT - Slide BG - Chương 4 - Đơn Kế Thừa
LTHĐT - Slide BG - Chương 4 - Đơn Kế Thừa
CHƯƠNG 4.
KỸ THUẬT KẾ THỪA
2
CÁC NỘI DUNG CHÍNH
4.2. Đa kế thừa
3
GIỚI THIỆU
Thừa kế là một kỹ thuật quan trọng trong lập trình hướng đối tượng. Kỹ
thuật này cho phép lập trình viên sử dụng lại mã lệnh chương trình. Từ đó giúp
làm giảm thời gian và công sức cần thiết để phát triển chương trình đồng thời
tăng sức tin cậy của chương trình đó
Kế thừa cho phép các lớp được xây dựng từ các lớp khác đã có
Một lớp được xây dựng kế thừa một lớp khác gọi là lớp dẫn xuất (derived
class).
Lớp dùng để xây dựng lớp dẫn xuất gọi là lớp cơ sở (base class).
4
GIỚI THIỆU
Lớp dẫn xuất sẽ kế thừa:
Lớp nào trong chương trình cũng có thể là một lớp cơ sở hay cụ thể hơn
một lớp dẫn xuất có thể là lớp cơ sở cho một lớp khác
5
GIỚI THIỆU
Một số sơ đồ minh họa tính kế thừa
Động vật
point
6
GIỚI THIỆU
Một số sơ đồ minh họa tính kế thừa
Công dân
Trưỏng bộ môn
7
GIỚI THIỆU
Tính kế thừa và đặc trưng của lớp kế thừa
Lớp cơ sở
Đặc trưng A
Các đặc trưng này
Đặc trưng B được định nghĩa ở
Đặc trưng C lớp cơ sở
class <Tên_lớp_cơ_sở>
{
// Nội dung lớp cơ sở
};
class <Tên_lớp_dẫn_xuất> : Kiểu_thừa_kế <Tên_lớp_cơ_sở>
{
//Nội dung lớp dẫn xuất
};
9
4.1. ĐƠN KẾ THỪA
Trong đó:
Kiểu_thừa_kế có thể là:
public
private
protected
Kiểu thừa kế chỉ rõ các thành phần của lớp cơ sở sẽ được kế
thừa theo cách nào.
Nếu được bỏ trống chương trình ngầm hiểu là private.
10
4.1. ĐƠN KẾ THỪA
Ví dụ
11
4.1. ĐƠN KẾ THỪA
class Box
{
float hight, weight;
public:
Lớp cơ sở
void Set()
{
cout<<"\n Input hight: "; cin>> hight;
cout<<"\n Input weight: "; cin>> weight;
}
void Display()
{
cout<<"hight = "<<hight<<"\tweight= "<<weight<<endl;
}
};
12
4.1. ĐƠN KẾ THỪA
class ColorBox: public Box
{ int color;
Lớp dẫn
public: xuất
void SetColor()
{ Set();
cout<<"\n Input color: "; cin>>color;
}
void DisplayColor()
{
Display();
cout<<"color= "<<color<<endl;
}
}; 13
4.1. ĐƠN KẾ THỪA
main()
{ Box a;
ColorBox b;
b.SetColor();
b.DisplayColor();
14
}
4.1. ĐƠN KẾ THỪA
15
4.1. ĐƠN KẾ THỪA
Chú ý:
Trong C++ không phải mọi hàm thành phần đều có thể truyền qua tính kế
thừa. Cụ thể một số trường hợp sau đây không cho phép sử dụng tính kế
thừa.
• Hàm tạo.
• Hàm hủy.
• Các toán tử mới do người dùng định nghĩa.
• Các toán tử gán do người dùng định nghĩa
• Quan hệ friend.
16
4.1. ĐƠN KẾ THỪA
Chú ý:
Lớp dẫn xuất không được phép truy nhập đến thành phần private của lớp
cơ sở.
Được phép khai báo bên trong lớp dẫn xuất các thành phần cùng tên với các
thành phần đã có trong lớp cơ sở.
<Hai thành phần cùng tên này có thể cùng kiểu hay khác kiểu. Lúc này bên trong một đối tượng của
lớp dẫn xuất có tới hai thành phần khác nhau có cùng tên, nhưng trong phạm vi lớp dẫn xuất tên chung
đó nhằm chỉ định thành phần được khai báo lại trong lớp dẫn xuất.>
Khi muốn chỉ định thành phần cùng tên trong lớp cơ sở, phải sử dụng
tên lớp cơ sở và toán tử phạm vi :: đặt trước tên thành phần đó với cú pháp:
<Tên_lớp_cơ_sở> :: <Tên_thành_phần>
Trong trường hợp chương trình sử dụng nhiều mức độ kế thừa khác nhau, toán
tử phạm vi vẫn cho phép truy nhập đến bất kể thành phần của lớp cơ sở nào.
17
4.1. ĐƠN KẾ THỪA
Ghi đè hàm thành phần của lớp cơ sở
Một lớp dẫn xuất có thể ghi đè hàm (overriding function) thành phần lớp cơ
sở. Hàm ghi đè và hàm bị ghi đè giống hệt nhau về tên, tham số và giá trị
trả về, chúng chỉ khác nhau ở vị trí, một hàm đặt trong lớp dẫn xuất và hàm
kia thì có mặt trong lớp cơ sở.
Một đối tượng lớp dẫn xuất gọi đến hàm ghi đè hoặc khi hàm đó được gọi
trong lớp dẫn xuất, hàm ghi đè của lớp dẫn xuất được gọi một cách tự
động. Muốn gọi đến hàm đó ở lớp cơ sở cần sử dụng toán tử định phạm
vi :: đặt trước tên hàm.
Ví dụ: Tạo lớp điểm trên mặt phẳng point có thành phần dữ liệu x,y. Lớp
điểm màu coloredpoint kế thừa từ lớp point và bổ sung thành phần màu
color:
18
4.1. ĐƠN KẾ THỪA
class point
{ float x,y;
public:
void Set(int a, int b)
{ x=a; y=b; }
void display()
{ cout<<"Toa do : "<<x<<" "<<y<<endl;}
};
class coloredpoint : public point
{ unsigned int color;
public:
void SetColor(int mau)
{ color= mau;}
void display() /* Ghi đè hàm display() của lớp cơ sở*/
{point::display(); /*gọi tới hàm cùng tên trong lớp cơ sở*/
cout<<"Mau "<<color<<endl;}
19
4.1. ĐƠN KẾ THỪA
main()
coloredpoint n ;
n.Set(4,5);
n.SetColor(6);
} 20
4.1. ĐƠN KẾ THỪA
Hàm tạo và hàm hủy trong kế thừa
Hàm tạo: Cú pháp định nghĩa hàm tạo lớp dẫn xuất:
Hàmtạolớpdẫnxuất(Dsthamsố) : Hàmtạolớpcơsở(Dsthamsố)
21
4.1. ĐƠN KẾ THỪA
Hàm tạo và hàm hủy trong kế thừa
Hàm tạo: Quy tắc định nghĩa hàm tạo lớp dẫn xuất như sau:
- Nếu lớp cơ sở và lớp dẫn xuất không định nghĩa hàm tạo thì hàm tạo
ngầm định của hai lớp sẽ đươc gọi theo đúng thứ tự.
- Nếu lớp cơ sở và lớp dẫn xuất có định nghĩa hàm tạo thì khi định nghĩa
hàm tạo lớp dẫn xuất luôn mô tả một lời gọi tới một trong các hàm tạo
tương ứng ở lớp cơ sở.
+ Hàm tạo không tham số của lớp dẫn xuất có thể có hoặc không cần
mô tả lại một lời gọi đến hàm tạo không tham số lớp cơ sở.
+ Hàm tạo có tham số của lớp dẫn xuất cần thiết phải mô tả lại một
lời gọi đến hàm tạo có tham số lớp cơ sở tương ứng. 22
4.1. ĐƠN KẾ THỪA
Hàm tạo và hàm hủy trong kế thừa
Hàm hủy: Hàm hủy thứ tự gọi ngược lại với hàm tạo. Khi hủy đối tượng
hàm hủy lớp dẫn xuất được gọi trước, rồi đến hàm hủy lớp cơ sở.
23
4.1. ĐƠN KẾ THỪA
Hàm tạo và hàm hủy trong kế thừa
Nhận xét:
Nếu muốn sử dụng hàm tạo không tham số của lớp cơ sở thì có thể
không cần mô tả cùng với định nghĩa của hàm tạo lớp dẫn xuất
Các tham số mà hàm tạo lớp dẫn xuất truyền cho hàm tạo lớp cơ sở
không nhất thiết lấy nguyên si từ các tham số nó nhận được mà có thể
được thay đổi đi ít nhiều.
Nếu lớp có thành phần dữ liệu con trỏ phải định nghĩa hàm hủy ngược lại
không bắt buộc.
24
4.1. ĐƠN KẾ THỪA
Hàm tạo và hàm hủy trong kế thừa
Nếu trong lớp dẫn xuất không khai báo tường minh hàm tạo sao chép, thì
công việc này được chương trình biên dịch đảm nhiệm nhờ định nghĩa hàm
tạo sao chép ngầm định.
Về nguyên tắc, trong định nghĩa của hàm tạo sao chép lớp dẫn xuất có
thể mô tả bất kỳ hàm tạo sao chép hoặc hàm tạo nào có mặt trong lớp cơ
sở. Lớp có thành phần dữ liệu con trỏ phải định nghĩa hàm tạo sao chép,
ngược lại không bắt buộc.
25
4.1. ĐƠN KẾ THỪA
Con trỏ và kế thừa
• Tương thích giữa đối tượng thuộc lớp dẫn xuất với đối tượng
thuộc lớp cơ sở:
Một đối tượng của lớp dẫn xuất có thể thay thế một đối tượng của lớp cơ
sở. Nghĩa là tất cả các thành phần của lớp cơ sở đều tìm thấy trong lớp
dẫn xuất.
Một đối tượng lớp cơ sở không thể thay thế một đối tượng lớp dẫn xuất.
26
4.1. ĐƠN KẾ THỪA
Con trỏ và kế thừa
• Tương thích giữa con trỏ lớp dẫn xuất và con trỏ lớp cơ sở :
Một con trỏ đối tượng lớp cơ sở có thể trỏ đến một đối tượng lớp dẫn
xuất.
Một con trỏ lớp dẫn xuất không thể trỏ đến đối tượng lớp cơ sở trừ
trường hợp ép kiểu.
27
4.1. ĐƠN KẾ THỪA
Con trỏ và kế thừa
• Tương thích giữa tham chiếu lớp dẫn xuất và tham chiếu lớp cơ
sở :
Một tham chiếu đối tượng lớp cơ sở có thể tham chiếu đến một đối
tượng lớp dẫn xuất.
Một tham chiếu lớp dẫn xuất không thể tham chiếu đến đối tượng lớp cơ
sở trừ trường hợp ép kiểu.
28
4.1. ĐƠN KẾ THỪA
Phạm vi truy xuất
• Khi thiết lập quan hệ kế thừa, vẫn cần phải quan tâm đến tính đóng gói
và che dấu thông tin. Vì vậy cần xác định ảnh hưởng của kế thừa đến phạm
vi truy xuất các thành phần của lớp. Hai vấn đề được đặt ra là:
- Hàm thành phần của lớp dẫn xuất có quyền truy xuất các thành phần
riêng tư của lớp cơ sở hay không.
- Các thành phần của lớp cơ sở, sau khi kế thừa xuống lớp dẫn xuất, thì
bên ngoài có quyền truy xuất đến các thành phần này thông qua đối tượng
của lớp dẫn xuất hay không.
29
4.1. ĐƠN KẾ THỪA
Phạm vi truy xuất
• Truy xuất các thành phần của lớp cơ sở từ lớp dẫn xuất
- Thành phần public: có thể được truy xuất từ bất cứ nơi nào (từ sau khai
báo lớp).
- Thành phần private: chỉ được truy xuất bởi các hàm thành phần và các
hàm friend của lớp cơ sở. <“Phạm vi lớp” chỉ mở rộng cho “bạn bè”, mà
không được mở rộng đến các lớp “con cháu”>
- Thành phần protected: Thành phần kiểu protected giống như private,
ngoại trừ một điều là các thành phần này có thể được truy nhập từ lớp dẫn
xuất. <Đặc biệt cần chú ý là các thành phần protected không thể truy nhập
từ bên ngoài lớp cơ sở hay lớp dẫn xuất từ lớp cơ sở đó>.
30
4.1. ĐƠN KẾ THỪA
Phạm vi truy xuất
• Nhận xét:
- Thuộc tính protected là phương tiện để tránh phải sửa đổi lớp cơ sở khi
có lớp dẫn xuất mới ra đời. Nhờ đó nó bảo đảm được tính đóng của một
lớp. Khai báo một thành phần nào có thuộc tính protected tương đương với
qui định trước tất cả các lớp con, cháu sau này đều là bạn của thành phần
đó.
- Thông thường ta dùng thuộc tính protected cho các thành phần dữ liệu
và thuộc tính public cho hàm thành phần.
31
4.1. ĐƠN KẾ THỪA
Phạm vi truy xuất
• Tổng kết khả năng truy nhập các thành phần trong một lớp:
• Khả năng truy nhập các thành phần trong một lớp:
33
4.1. ĐƠN KẾ THỪA
Các kiểu kế thừa
35
4.1. ĐƠN KẾ THỪA
- Cách cài đặt một số hàm đặc biệt trong lớp như hàm tạo, hàm
tạo sao chép, hàm hủy,….
37
CÂU HỎI CUỐI CHƯƠNG
Câu 1: Giải thích sự khác nhau giữa các thành phần protected và private?
Câu 2: Hàm tạo và hàm hủy hoạt động như thế nào trong lớp kế thừa?
Câu 4: Tìm lỗi sai của đoạn chương trình sau đây
class A
{ public:
void func();
};
class B: private A
{};
main()
{ A a;
B b;
a.func();
b.func();
A *pA= &b;
B *pb= &a;
38
}
BÀI TẬP
Bài tập 1: Xây dựng lớp Người gồm có các thành phần Họ tên và Năm
sinh. Viết các phương thức của lớp như nhập, hiển thị dữ liệu.
Xây dựng lớp Thí sinh kế thừa lớp này, trong lớp Thí sinh có Số báo
danh và Điểm các môn toán, lý, hóa. Hãy xây dựng thêm các phương thức
nhập, xuất và khai báo mảng có kiểu là Thisinh để quản lý danh sách các thí
sinh. Viết chương trình với các công việc sau:
- Hiển thị danh sách thí sinh có tổng điểm ba môn tăng dần;
- Thống kê xem có bao nhiêu phần trăm thí sinh đạt yêu cầu (cả ba môn
có điểm lớn hơn hoặc bằng 5). 39
BÀI TẬP
Bài tập 2:
Xây dựng lớp Sản phẩm bao gồm: Mã sản phẩm, Tên sản
phẩm, Năm sản xuất và các phương thức nhập, xuất.
Xây dựng tiếp lớp Tivi có thêm các thuộc tính Chiều dài, Chiều
rộng của màn hình. Hãy xây dựng phương thức tính diện tích của
màn hình của lớp Tivi.
Viết chương trình nhập vào các đối tượng của lớp Tivi, sau đó
sắp xếp tăng dần theo diện tích màn hình của các đối tượng này
40