Hàm hoàn toàn ả o phải ñịnh nghĩa lại trong lớp con.
Trang 1TH Ừ A K Ế
Chương 8
1
• Thừa kế ñơn
• Thừa kế bội
• Liên kết tĩnh và liên kết ñộng
2
Khái ni ệ m
K ế th ừ a t ừ các l ớ p ñ ã có t ừ tr ướ c.
=> Không ph ả i ñị nh ngh ĩ a nhi ề u Thi ế t k ế ñơ n gi ả n h ơ n.
Ích l ợ i: có th ể t ậ n d ụ ng l ạ i
Các thuộc tính chung
Các hàm có thao tác tương tự
• Khai báo
3
L Ớ P CHA
L Ớ P CHA
(Lớp cơ sở)
L Ớ P CON
L Ớ P CON
(lớp dẫn xuất)
class < ớ p con>
: < d ạ ng th ừ a k ế><L ớ p cha> {
// khai báo lớp con
…
};
Các hàm có thao tác tương tự
• D ạ ng th ừ a k ế
L ớ p c ơ s ở Th ừ a k ế public Th ừ a k ế private Th ừ a k ế protected
public public private protected
protected protected private protected
protected protected private protected
4
class A {
int x;
void Fx();
public:
int y;
void Fy();
protected:
int z;
void Fz();
};
// Th ừ a k ế d ng private
// A là l ớ p c ơ s riêng c ủ a C
class C : private A {……… };
// A là l ớ p c ơ s chung c ủ a D
class D : public A {……… };
// A: l ớ p c ơ s ñượ c b ả o v ệ
class E : protected A {……… };
Trang 2• Quyề n truy xu ấ t trong l ớ p con
– L ớ p con có tất cả thành phần (thu ộ c tính + ph ươ ng th ứ c)
c ủ a l ớ p cha.
– Không th ể truy xu ấ t thành ph ầ n private c ủ a l ớ p cha.
5
class Diem {
int x, y;
public:
void GanDiem(int h,int t) { x = h; y = t; }
void HienDiem()
class DiemMau : public
Diem {
int mau;
public:
void KTao(int h,int
t,int m)
{ GanDiem(h,t); mau=m; }
void Hien()
6
{
cout<<“(”
<<x<<“,”<<y
<<“)”;}
void DoiDiem(int dx,
int dy) { x += dx; y += dy; }
};
void Hien() { HienDiem();
cout<<mau; }
};
void main() {
DiemMau a;
a.KTao(2,5,0);
a.HienDiem();
a.DoiDiem(7,8); a.Hien(); }
• Hàm xây d ự ng và hàm h ủ y
- Khi khởi tạo ñối tượng : hàm xây d ự ng c ủ a l ớ p cha s ẽ ñượ c
g ọ i tr ướ c, sau ñ ó là hàm xây d ự ng c ủ a l ớ p con.
Trong hàm xây dựng của lớp con phải g i hàm xây
dựng của lớp chañể khởi tạo thuộc tính của lớp cha
- Khi hủy bỏ ñối tượng : hàm h ủ y c ủ a l ớ p con s ẽ ñượ c
A
B
C
- Khi hủy bỏ ñối tượng : hàm h ủ y c ủ a l ớ p con s ẽ ñượ c
g ọ i tr ướ c, sau ñ ó m ớ i là hàm h ủ y c ủ a l ớ p cha.
• Hàm xây d ự ng và hàm h ủ y
class Diem {
int x, y;
public:
Diem() { x=y=0;}
Diem(int h, int t)
class DiemMau : public Diem {
int mau;
public:
DiemMau() :Diem() { mau=0; }
DiemMau(int h,int t,int m)
Diem(int h, int t) { x=h; y=t;}
Diem(const Diem& d) { x=d.x; y=d.y;}
};
DiemMau(int h,int t,int m) :Diem(h,t) { mau=m; }
DiemMau(const DiemMau& d1) :Diem(d1){ mau=d1.mau; }
};
void main() { DiemMau a(2,5,3);
DiemMau b;
DiemMau c = a;
}
2 5 3
x y mau
Diem(2,5) mau=3;
Trang 3• Hàm xây d ự ng và hàm h ủ y
class SinhVien {
char mssv[9];
char* hoten;
int namsinh;
float diemtb;
public:
SinhVien() ;
class SinhVienNuocNgoai
: public SinhVien {
char* nuoc;
char sopassport[12];
public:
SinhVienNuocNgoai()
: SinhVien() { nuoc = new char[30];
strcpy(sopassport,””);
}
SinhVienNuocNgoai(const
SinhVienNuocNgoai & s)
9
SinhVien() ;
SinhVien(char*,char*,int,float);
SinhVien(const SinhVien&);
void operator =(const SinhVien&);
~SinhVien() { delete[] hoten; }
void Nhap();
void In();
};
// ðị nh ngh ĩ a các hàm thành viên
…
SinhVienNuocNgoai & s)
: SinhVien( s ) { nuoc = strdup(s.nuoc);
strcpy( sopassport , s.sopassport);
}
~SinhVienNuocNgoai() { delete[] nuoc;
}
};
• Tái ñị nh ngh ĩ a d ữ li ệ u thành viên
– Thu ộ c tính c ủ a l ớ p con trùng tên thu ộ c tính c ủ a l ớ p cha – Trong l ớ p con, n ế u ta truy xu ấ t ñế n d ữ li ệ u trùng tên ñ ó thì
s ẽ truy xu ấ t ñế n d ữ li ệ u c ủ a l ớ p con.
– Truy xu ấ t d ữ li ệ u l ớ p cha : <Tên l ớ p cha> :: <d ữ li ệ u>
class LopCha { LopCon :: LopCon(): LopCha()
10
class LopCha {
public:
int a;
LopCha() { a= 0; } };
class LopCon : public LopCha {
public:
int a;
LopCon();
void Hien();
};
LopCon :: LopCon(): LopCha() { a = 1; }
void LopCon ::Hien()
{ cout << a << LopCha ::a;
}
void main() {
LopCon x;
x.Hien();
cout << x.a
<< x.LopCha ::a;
}
• Tái ñị nh ngh ĩ a hàm thành viên
– Hàm thành viên c ủ a l ớ p con trùng tên v ớ i hàm thành viên
c ủ a l ớ p cha.
– G ọ i hàm trùng tên => g ọ i hàm c ủ a l ớ p con.
– G ọ i hàm c ủ a l ớ p cha : <Tên l ớ p cha> :: <tên hàm>(…)
class Diem {
int x, y;
public:
void Hien() {
cout<<“(”<<x<<“,”
void DiemMau :: :: Hien()
{
Diem::Hien();
cout<<“ mau ”<<mau; }
cout<<“(”<<x<<“,”
<<y<<“)”;}
};
class DiemMau :public Diem{
int mau;
public:
void Hien();
};
void main() {
DiemMau a(2,5,4);
a.Hien();
a.DiemMau :: ::Hien();
DiemMau b=a;
b.Diem :: ::Hien();
}
Trang 4Th ừ a k ế b ộ i
Th ừ a k ế b ộ i
• Ư u ñ i ể m
– T ậ n d ụ ng ñượ c nh ữ ng thành ph ầ n ñ ã có s ẵ n c ủ a l ớ p
cha:
• Dữ liệu thành viên
• Hàm thành viên
– Thu ậ n l ợ i khi s ử d ụ ng k ế t h ợ p v ớ i hàm ả o.
– Thu ậ n l ợ i khi s ử d ụ ng k ế t h ợ p v ớ i hàm ả o.
13
SinhViên
SinhViênT ạ iCh ứ c
–mã số
NhânViên
–mã số
Dữ liệu của SinhViên
Dữ liệu của NhânViên
Dữ liệu của SinhViênTạiChức
Tạo rañối tượng
Th ừ a k ế b ộ i
Th ừ a k ế b ộ i
Vấn ñề cần lưu ý khi sử dụng thừa kế bội
C ạ nh tranh trong th ừ a k ế b ộ i.
Thi ế t k ế s ơ ñồ th ừ a k ế ph ả i ñ úng ý ngh ĩ a.
Nên h ạ n ch ế và c ẩ n th ậ n khi s ử d ụ ng th ừ a k ế b ộ i.
14
Nên h ạ n ch ế và c ẩ n th ậ n khi s ử d ụ ng th ừ a k ế b ộ i.
class XeDien {
int loaibinhdien;
int thoigian;
float tocdo;
public:
XeDien() { … }
XeDien(int b,
int tg, float td) { … }
};
class XeDap {
char loai[10]; char* mau;
int chieucao;
public:
XeDap() { … }
XeDap(char* l,char* m,int c){…}
};
Th ừ a k ế b ộ i
Th ừ a k ế b ộ i
class XeDapDien :public XeDap, public XeDien{
public:
XeDapDien();
XeDapDien( char*, char*, int ,
int , int , float );
};
XeDapDien :: XeDapDien (): XeDap(), XeDien(){ … }
XeDapDien :: XeDapDien ( char* a, char* b,
int c, int d, int e, float f )
: XeDap(a, b, c), XeDien(d,e,f) { … }
Khai báo lớp trong
thừa kế bội
Gọi hàm xây dựng
của các lớp cha
• S ự t ươ ng thích gi ữ a ñố i t ượ ng c ủ a l ớ p con và ñố i t ượ ng
c ủ a l ớ p cha
L Ớ PCHA
L Ớ PCHA
L Ớ PCON
L Ớ PCON
void main() {
LopCha a;
LopCon b;
a = b;
b = a; // Sai
Có thểgán Cha = Con
Hổn
L Ớ PCON
L Ớ PCON
class LopCha {
… … };
class LopCon
: public
LopCha {
… … };
b = a; // Sai
LopCha *pa;
pa = &a;
LopCon *pb;
pb = &b;
pa = &b;
pb = &a; //
Sai
Hổn
Con trỏcủa lớp cha có
thểtrỏ ñến
ñối tượng
của lớp con
Trang 5• Liên k ế t t ĩ nh
– Con tr ỏ thu ộ c l ớ p nào, khi g ọ i hàm s ẽ g ọ i hàm c ủ a l ớ p ñ ó.
– Tính ch ấ t c ủ a ñố i t ượ ng ñượ c nh ậ n bi ế t khi biên d ị ch CT.
class LopCha {
…
public:
void main() {
LopCha a;
LopCha *pa=&a;
17
public:
…
void HamThanhVien() {
cout<<“Ham cua Lop Cha”;}
};
class LopCon :public LopCha {
…
public:
void HamThanhVien() {
cout<<“Ham cua Lop Con”;}
};
LopCha *pa=&a;
//Lớ p cha
pa->HamThanhVien();
LopCon b;
LopCon *pb=&b;
//Lớ p con
pb->HamThanhVien();
pa= &b;
//Lớ p cha
pa->HamThanhVien();
pb= &a; //Báo l ỗ
}
• Hàm ả o
– Cú pháp: khai báo thêm t ừ khóa virtual tr ướ c hàm.
– Dùng chung v ớ i tính liên k ế t ñộ ng => tính ñ a hình
{
18
{
public:
virtual void HamAo() { … }
};
{
public:
void HamAo() { … } };
Hàm hoàn toàn ả o
Cú pháp: ch ỉ khai báo tên trong l ớ p cha và gán=0.
Hàm hoàn toàn ả o phải ñịnh nghĩa lại trong lớp con
class LopCha
{
public:
virtual void HamHT_Ao()=0;
};
class LopCon :public LopCha
{
public:
void HamHT_Ao() { … } };
• Liên kế t ñộ ng
– Con tr ỏ ñ ang tr ỏ ñế n ñố i t ượ ng nào, khi g ọ i hàm ả o s ẽ g ọ i hàm c ủ a l ớ p t ạ o ra ñố i t ượ ng ñ ó.
– Tính ch ấ t c ủ a ñố i t ượ ng ñượ c nh ậ n bi ế t khi ñ ang th ự c thi.
class LopCha {
public:
void main() {
LopCha a;
public:
virtual void HamAo() {
cout<<“Ham cua Lop Cha”;
} };
class LopCon : public LopCha{
public:
void HamAo() {
cout<<“Ham cua Lop Con”;
} };
LopCha a;
LopCha *pa=&a;
pa->HamAo(); //Lớp cha
LopCon b;
LopCon *pb=&b;
pb->HamAo(); //Lớp con
pa= &b;
pa->HamAo(); //Hàm lớ p con
pb= &a; //Báo l ỗ
}