Thừa kế đơn 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.. Nguyễn Công Huy – Khoa CNTT&TT 5Thừa kế đơn Hàm xây dựng và hàm hủy
Trang 1Nguyễn Công Huy – Khoa CNTT&TT 1
THỪA KẾ
Thừa kế đơn
Thừa kế bội
Liên kết tĩnh và liên kết động
Trang 2Thừa kế đơn
Khai báo (Lớp cơ sở) LỚP CHA
LỚP CON
(lớp dẫn xuất)
class <Lớp con>
: < dạng thừa kế> <Lớp cha> { // khai báo lớp con
… };
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ự
Trang 3Nguyễn Công Huy – Khoa CNTT&TT 3
Thừa kế đơn
Dạng thừa kế
Lớp cơ sở Thừa kế public Thừa kế private Thừa kế protected
protected protected private protected
class A {
int x;
void Fx ();
public:
int y;
void Fy ();
protected:
int z;
void Fz ();
};
class B : A { // Thừa kế dạng private
……
};
class C : private private A { // A là lớp cơ sở riêng của C
………
};
class D : public public A { // A là lớp cơ sở chung của D
………
};
class E : protected protected A { // A: lớp cơ sở được bảo vệ
………
};
Trang 4Thừa kế đơn
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.
class Diem {
int x, y;
public:
void GanDiem(int h, int t)
{ x = h; y = t; }
void HienDiem()
{ cout<<“(”<<x<<“,”<<y<<“)”;}
void DoiDiem(int dx, int dy)
{ x += dx; y += dy; }
};
class DiemMau : public : public Diem {
int mau;
public: void KTao(int h,int t,int m) { GanDiem(h,t); mau=m; } void Hien()
{ HienDiem(); cout<<mau; }
};
void main() { DiemMau a; a.KTao(2,5,0); a.HienDiem();
a.DoiDiem(7,8); a.Hien();
Trang 5Nguyễn Công Huy – Khoa CNTT&TT 5
Thừa kế đơn
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.
A
B
C
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 gọi trước, sau đó mới là hàm hủy của lớp cha.
Trang 6Thừa kế đơn
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)
{ x=h; y=t; }
Diem(const Diem& d)
{ x=d.x; y=d.y; }
};
class DiemMau :: public Diem { int mau;
public: DiemMau () : Diem() { mau=0; } 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
a
Diem(2,5) mau=3;
Trang 7Nguyễn Công Huy – Khoa CNTT&TT 7
Thừa kế đơn
Hàm xây dựng và hàm hủy
class SinhVien {
char mssv[9];
char* hoten;
int namsinh;
float diemtb;
public :
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
…
class SinhVienNuocNgoai
: public public SinhVien {
char* nuoc;
char sopassport[12];
public : SinhVienNuocNgoai()
: SinhVien() { nuoc = new char[30];
strcpy(sopassport,””);
}
SinhVienNuocNgoai & s) : SinhVien( s ) {
nuoc = strdup(s.nuoc);
strcpy( sopassport , s.sopassport);
} ~SinhVienNuocNgoai() { delete[] nuoc;
}
};
Trang 8Thừa kế đơn
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 {
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;
}
Trang 9Nguyễn Công Huy – Khoa CNTT&TT 9
Thừa kế đơn
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<<“,”<<y<<“)”;}
};
class DiemMau : public : public Diem {
int mau;
public:
void Hien();
};
void DiemMau :: Hien() ::
{ Diem::Hien();
cout<<“ mau ”<<mau;
}
void main() { DiemMau a(2,5,4);
a.Hien();
a.DiemMau ::Hien(); ::
DiemMau b=a;
b.Diem ::Hien(); ::
}
Trang 10Thừ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.
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.
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
Trang 11Nguyễn Công Huy – Khoa CNTT&TT 11
Thừa kế bội
class XeDien { int loaibinhdien;
int thoigian;
float tocdo;
public : XeDien() { … } XeDien( int b, int tg, float td) { … } …
};
class XeDapDien : public XeDap, public XeDien {
…
public :
XeDapDien();
XeDapDien( char *, cha r*, 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) { … }
…
class XeDap {
char loai[10];
char * mau;
int chieucao;
public :
XeDap() { … }
XeDap( char * l, char * m, int c) { … }
…
};
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
Trang 12Liên kết tĩnh và liên kết động
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ỚPCON
class LopCha {
…
…
};
class LopCon
: public LopCha {
…
…
};
void main() {
LopCha a;
LopCon b;
a = b;
b = a; // Sai
LopCha *pa;
pa = &a;
LopCon *pb;
pb = &b;
pa = &b;
pb = &a; // Sai
}
Con trỏ của lớp cha
có thể trỏ đến đối tượng của lớp con
Có thể gán Cha = Con
Hổn
Trang 13Nguyễn Công Huy – Khoa CNTT&TT 13
Liên kết tĩnh và liên kết động
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 HamThanhVien() {
cout<<“Ham cua Lop Cha”;
}
};
class LopCon : public LopCha {
public:
…
void HamThanhVien() {
cout<<“Ham cua Lop Con”;
}
};
void main() {
LopCha a;
LopCha *pa=&a;
pa->HamThanhVien(); //Lớp cha
LopCon b;
LopCon *pb=&b;
pb->HamThanhVien(); //Lớp con
pa= &b;
pa->HamThanhVien(); //Lớp cha
pb= &a; //Báo lỗi
}
Trang 14Liên kết tĩnh và liên kết động
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
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 HamAo()
{ … } };
class LopCon : public LopCha {
public: void HamAo()
{ … } };
class LopCha {
public:
virtual void HamHT_Ao()=0;
};
class LopCon : public LopCha {
public: void HamHT_Ao() { … } };
Trang 15Nguyễn Công Huy – Khoa CNTT&TT 15
Liên kết tĩnh và liên kết động
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:
…
virtual void HamAo() {
cout<<“Ham cua Lop Cha”;
}
};
class LopCon : public LopCha {
public:
…
void HamAo() {
cout<<“Ham cua Lop Con”;
}
};
void main() {
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ỗi
}