4. Phöông thöùc aûo vaø tính ña 4. Phöông thöùc aûo vaø tính ña hìnhhình hìnhhình
1
Noäi dung Noäi dung
Baøi toaùn quaûn lyù moät danh 1 1 Baøi toaùn quaûn lyù moät danh saùch caùc ñoái töôïng khaùc kieåu saùch caùc ñoái töôïng khaùc kieåu Phöông thöùc aûo 3 3 Phöông thöùc aûo Phöông thöùc aûo thuaàn tuyù 4 4 Phöông thöùc aûo thuaàn tuyù 4 4 Phöông thöùc aûo thuaàn tuyù Phöông thöùc aûo thuaàn tuyù
2
1 B.toaùn q.lyù caùc ñ.töôïng khaùc kieåu 1 B.toaùn q.lyù caùc ñ.töôïng khaùc kieåu
- Giaû söû ta caàn quaûn lyù moät danh saùch caùc ñoái töôïng coù kieåu coù theå khaùc nhau, ta caàn giaûi quyeát hai vaán ñeà: Caùch löu tröõ vaø thao taùc xöû lyù.
- Xeùt tröôøng hôïp cuï theå, caùc ñoái töôïng coù theå laø ngöôøi, sinh
vieân hoaëc coâng nhaân.
- Veà löu tröõ: Ta coù theå duøng union, trong tröôøng hôïp naøy moãi - Veà löu tröõ: Ta coù theå duøng union, trong tröôøng hôïp naøy moãi ñoái töôïng phaûi coù kích thöôùc chöùa ñöôïc ñoái töôïng coù kích ñoái töôïng phaûi coù kích thöôùc chöùa ñöôïc ñoái töôïng coù kích thöôùc lôùn nhaát. Ñieàu naøy gaây laõng phí khoâng gian löu tröõ. Moät caùch thay theá laø löu tröõ ñoái töôïng baèng ñuùng kích thöôùc cuûa noù vaø duøng moät danh saùch (maûng, dslk,...) caùc con troû ñeå quaûn lyù caùc ñoái töôïng.
- Veà thao taùc, phaûi thoaû yeâu caàu ña hình: Thao taùc coù hoaït ñoäng khaùc nhau öùng vôùi caùc loaïi ñoái töôïng khaùc nhau. Coù hai caùch giaûi quyeát laø vuøng choïn kieåu vaø phöông thöùc aûo.
3
Duøng vuøng choïn kieåu Duøng vuøng choïn kieåu (cid:1) Veà löu tröõ: Ta seõ duøng moät maûng caùc con troû ñeán lôùp cô sôû
ñeå coù theå troû ñeán caùc ñoái töôïng thuoäc lôùp con.
(cid:1) Xeùt lôùp Ngöôøi vaø caùc lôùp keá thöøa sinh vieân vaø coâng nhaân. Thao taùc ta quan taâm laø xuat. Ta caàn baûo ñaûm thao taùc xuaát aùp duïng cho lôùp sinh vieân vaø lôùp coâng nhaân khaùc nhau.
4
Ví duï minh hoaï Ví duï minh hoaï
class Nguoi { protected:
char *HoTen; int NamSinh;
public:
Nguoi(char *ht, int ns):NamSinh(ns) {HoTen = strdup(ht);} strdup(ht);} ~Nguoi() {delete [] HoTen;} void An() const { cout << HoTen << " an 3 chen com";} void Ngu() const { cout << HoTen << " ngu ngay 8 tieng";} void Xuat() const { cout << "Nguoi, ho ten: " << HoTen << " sinh " << NamSinh; }
5
};
Ví duï minh hoaï Ví duï minh hoaï
class SinhVien : public Nguoi { protected:
char *MaSo;
public:
SinhVien(char *n, char *ms, int ns) : Nguoi(n,ns) { MaSo = strdup(ms);} ~SinhVien() {delete [] MaSo;} ~SinhVien() {delete [] MaSo;} void Xuat() const { cout << "Sinh vien " << HoTen << ", ma so " << MaSo;}
}; class NuSinh : public SinhVien { public:
6
NuSinh(char *ht, char *ms, int ns) : SinhVien(ht,ms,ns) {} void An() const { cout << HoTen << " ma so " << MaSo << " an 2 to pho";}
};
Ví duï minh hoaï Ví duï minh hoaï
class CongNhan : public Nguoi { protected:
double MucLuong;
public:
CongNhan(char *n, double ml, int ns) : Nguoi(n,ns), MucLuong(ml) { } void Xuat() const { cout << "Cong nhan, ten " void Xuat() const { cout << "Cong nhan, ten " << HoTen << " muc luong: " << MucLuong;}
}; void XuatDs(int n, Nguoi *an[]) {
for (int i = 0; i < n; i++) {
an[i]->Xuat(); cout << "\n";
}
7
}
Ví duï minh hoaï Ví duï minh hoaï
const int N = 4; void main() {
Nguoi *a[N]; a[0] = new SinhVien("Vien Van Sinh", ”200001234",
1982);
a[1] = new NuSinh("Le Thi Ha Dong", ”200001235",
1984);
a[2] = new CongNhan("Tran Nhan Cong", 1000000, a[2] = new CongNhan("Tran Nhan Cong", 1000000,
1984);
a[3] = new Nguoi("Nguyen Thanh Nhan", 1960); XuatDs(4,a);
8
}
Duøng vuøng choïn kieåu Duøng vuøng choïn kieåu
(cid:1) Xuaát lieäu cho ñoaïn chöông trình treân nhö sau: Nguoi, ho ten: Vien Van Sinh sinh 1982 Nguoi, ho ten: Le Thi Ha Dong sinh 1984 Nguoi, ho ten: Tran Nhan Cong sinh 1984 Nguoi, ho ten: Nguyen Thanh Nhan sinh 1960 (cid:1) Taát caû moïi ñoái töôïng ñeàu ñöôïc quan ñieåm nhö ngöôøi vì thao taùc ñöôïc thöïc hieän thoâng qua con troû ñeán lôùp Ngöôøi. thao taùc ñöôïc thöïc hieän thoâng qua con troû ñeán lôùp Ngöôøi. (cid:1) Ñeå baûo ñaûm xuaát lieäu töông öùng vôùi ñoái töôïng, phaûi coù caùch nhaän dieän ñoái töôïng, ta theâm moät vuøng döõ lieäu vaøo lôùp cô sôû ñeå nhaän dieän, vuøng naøy coù giaù trò phuï thuoäc vaøo loaïi cuûa ñoái töôïng vaø ñöôïc goïi laø vuøng choïn kieåu.
(cid:1) Moät caùch tieáp caän khaùc laø duøng phöông thöùc aûo.
9
2. Phöông thöùc aûo 2. Phöông thöùc aûo (cid:1) Con troû thuoäc lôùp cô sôû coù theå troû ñeán lôùp con:
Nguoi* pn = new SinhVien(“Le Vien Sinh”,
(cid:1) Ta mong muoán thoâng qua con troû thuoäc lôùp cô sôû coù theå truy xuaát haøm thaønh phaàn ñöôïc ñònh nghóa laïi ôû lôùp con: pn->Xuat(); // Mong muon: goi Xuat cua lop sinh
200001234, 1982);
(cid:1) Phöông thöùc aûo cho pheùp giaûi quyeát vaán ñeà. Ta qui ñònh
moät haøm thaønh phaàn laø phöông thöùc aûo baèng caùch theâm töø khoaù virtual vaøo tröôùc khai baùo haøm.
(cid:1) Trong ví duï treân, ta theâm töø khoaù virtual vaøo tröôùc khai
baùo cuûa haøm xuat.
10
// vien, thuc te: goi Xuat cua lop // Nguoi
Phöông thöùc aûo Phöông thöùc aûo
class Nguoi { protected:
char *HoTen; int NamSinh;
public:
Nguoi(char *ht, int ns):NamSinh(ns) {HoTen = strdup(ht);} strdup(ht);} ~Nguoi() {delete [] HoTen;} void An() const { cout << HoTen << " an 3 chen com";} void Ngu() const { cout << HoTen << " ngu ngay 8 tieng";} virtual void Xuat() const { cout << "Nguoi, ho ten: " << HoTen << " sinh " << NamSinh; }
11
};
Phöông thöùc aûo Phöông thöùc aûo
class SinhVien : public Nguoi { protected:
char *MaSo;
public:
SinhVien(char *n, char *ms, int ns) : Nguoi(n,ns) { MaSo = strdup(ms);} ~SinhVien() {delete [] MaSo;} ~SinhVien() {delete [] MaSo;} void Xuat() const { cout << "Sinh vien " << HoTen << ", ma so " << MaSo;}
}; class NuSinh : public SinhVien { public:
12
NuSinh(char *ht, char *ms, int ns) : SinhVien(ht,ms,ns) {} void An() const { cout << HoTen << " ma so " << MaSo << " an 2 to pho";}
};
Phöông thöùc aûo Phöông thöùc aûo
class CongNhan : public Nguoi { protected:
double MucLuong;
public:
CongNhan(char *n, double ml, int ns) : Nguoi(n,ns), MucLuong(ml) { } void Xuat() const { cout << "Cong nhan, ten " void Xuat() const { cout << "Cong nhan, ten " << HoTen << " muc luong: " << MucLuong;}
};
void XuatDs(int n, Nguoi *an[]) {
for (int i = 0; i < n; i++) {
an[i]->Xuat(); cout << "\n";
13
}
}
Phöông thöùc aûo Phöông thöùc aûo
const int N = 4; void main() {
Nguoi *a[N]; a[0] = new SinhVien("Vien Van Sinh", "200001234", 1982); a[1] = new NuSinh("Le Thi Ha Dong", "200001235", 1984); "200001235", 1984); a[2] = new CongNhan("Tran Nhan Cong", 1000000, 1984); a[3] = new Nguoi("Nguyen Thanh Nhan", 1960); XuatDs(4,a);
(cid:1) Phöông thöùc aûo xuat ñöôïc khai baùo ôû lôùp Nguoi cho pheùp söû duïng con troû ñeán lôùp cô sôû (Nguoi) nhöng troû ñeán moät ñoái töôïng thuoäc lôùp con (Sinh vieân, coâng nhaân) goïi ñuùng thao taùc ôû lôùp con:
14
}
Phöông thöùc aûo Phöông thöùc aûo
Nguoi *pn; pn = new SinhVien("Vien Van Sinh", "200001234",
1982);
(cid:1) Con troû pn thuoäc lôùp Nguoi nhöng troû ñeán ñoái töôïng sinh
vieân, vì vaäy pn->Xuat() thöïc hieän thao taùc xuaát cuûa lôùp sinh vieân.
(cid:1) Trôû laïi ví duï treân, khi i a[i] laàn löôït troû ñeán caùc ñoái töôïng (cid:1) Trôû laïi ví duï treân, khi i a[i] laàn löôït troû ñeán caùc ñoái töôïng
thuoäc caùc loaïi khaùc nhau, thao taùc töông öùng vôùi lôùp seõ ñöôïc goïi.
(cid:1) Duøng phöông thöùc aûo khaéc phuïc ñöôïc caùc nhöôïc ñieåm cuûa
caùch tieáp caän duøng vuøng choïn kieåu:
(cid:1) Thao taùc ñôn giaûn khoâng phaûi duøng switch/case vì vaäy khoù
sai, deã söûa.
15
pn->Xuat(); // Goi thao tac xuat cua lop Sinh vien
Theâm lôùp con môùi Theâm lôùp con môùi (cid:1) Duøng phöông thöùc aûo, ta deã daøng naâng caáp söûa chöõa. Vieäc theâm moät loaïi ñoái töôïng môùi raát ñôn giaûn, ta khoâng caàn phaûi söûa ñoåi thao taùc xöû lyù (haøm XuatDs). Qui trình theâm chæ laø xaây döïng lôùp con keá thöøa töø lôùp cô sôû hoaëc caùc lôùp con ñaõ coù vaø ñònh nghóa laïi phöông thöùc (aûo) ôû lôùp môùi taïo neáu caàn class CaSi : public Nguoi class CaSi : public Nguoi { protected:
double CatXe;
public:
CaSi(char *ht, double cx, int ns) : Nguoi(ht,ns), CatXe(cx) {} void Xuat() const { cout << "Ca si, " << HoTen << " co cat xe " << CatXe;}
16
};
Theâm lôùp con môùi Theâm lôùp con môùi
void XuatDs(int n, Nguoi *an[]) {
for (int i = 0; i < n; i++) {
an[i]->Xuat(); cout << "\n";
}
(cid:1) Haøm XuatDs khoâng thay ñoåi, nhöng noù coù theå hoaït ñoäng
cho caùc loaïi ñoái töôïng ca só thuoäc lôùp môùi ra ñôøi.
(cid:1) Coù theå xem nhö thao taùc XuatDs ñöôïc vieát tröôùc cho caùc
lôùp con chaùu chöa ra ñôøi.
17
} }
Caùc löu yù khi söû duïng phöông thöùc aûo Caùc löu yù khi söû duïng phöông thöùc aûo
(cid:1) Phöông thöùc aûo chæ hoaït ñoäng thoâng qua con troû. (cid:1) Muoán moät haøm trôû thaønh phöông thöùc aûo coù hai caùch: Khai baùo vôùi töø khoaù virtual hoaëc haøm töông öùng ôû lôùp cô sôû ñaõ laø phöông thöùc aûo.
(cid:1) Phöông thöùc aûo chæ hoaït ñoäng neáu caùc haøm ôû lôùp cô sôû vaø
lôùp con coù nghi thöùc giao tieáp gioáng heät nhau. (cid:1) Neáu ôû lôùp con ñònh nghóa laïi phöông thöùc aûo thì seõ goïi Neáu ôû lôùp con ñònh nghóa laïi phöông thöùc aûo thì seõ goïi phöông thöùc ôû lôùp cô sôû (gaàn nhaát coù ñònh nghóa).
18
Phöông thöùc huyû boû aûo Phöông thöùc huyû boû aûo (cid:1) Trong ví duï quaûn lyù danh saùch caùc ñoái töôïng thuoäc caùc lôùp Nguoi, SinhVien, CongNhan, … Thao taùc doïn deïp ñoái töôïng laø caàn thieát. const int N = 4; void main() {
Nguoi *a[N]; a[0] = new SinhVien("Vien Van Sinh", a[0] = new SinhVien("Vien Van Sinh", "20001234", 1982); a[1] = new NuSinh("Le Thi Ha Dong", "20001235", 1984); a[2] = new CongNhan("Tran Nan Cong", 1000000, 1984); a[3] = new Nguoi("Nguyen Thanh Nhan", 1960); XuatDs(4,a); for (int i = 0; i < 4; i++)
19
delete a[i];
}
Phöông thöùc huyû boû aûo Phöông thöùc huyû boû aûo
(cid:1) Thoâng qua con troû thuoäc lôùp cô sôû Nguoi, chæ coù phöông
thöùc huyû boû cuûa lôùp Nguoi ñöôïc goïi.
(cid:1) Ñeå baûo ñaûm vieäc doïn deïp laø ñaày ñuû, ta duøng phöông thöùc
huyû boû aûo. class Nguoi { protected: protected:
char *HoTen; int NamSinh;
public:
20
Nguoi(char *ht, int ns):NamSinh(ns) {HoTen = strdup(ht);} virtual ~Nguoi() {delete [] HoTen;} virtual void Xuat(ostream &os) const { os << "Nguoi, ho ten: " << HoTen << " sinh " << NamSinh; } void Xuat() const { Xuat(cout); }
};
3. PT aûo th tuyù vaø lôùp csôû tr töôïng 3. PT aûo th tuyù vaø lôùp csôû tr töôïng (cid:1) Lôùp cô sôû tröøu töôïng laø lôùp cô sôû khoâng coù ñoái töôïng naøo thuoäc chính noù. Moät ñoái töôïng thuoäc lôùp cô sôû tröøu töôïng phaûi thuoäc moät trong caùc lôùp con. (cid:1) Xem chöông trình nguoàn t_hinh.cpp
21
Phöông thöùc aûo thuaàn tuyù vaø lôùp cô sôû tröøu töôïng Phöông thöùc aûo thuaàn tuyù vaø lôùp cô sôû tröøu töôïng
(cid:1) Khi lôùp coù phöông thöùc aûo thuaàn tuyù, lôùp trôû thaønh lôùp cô sôû tröøu töôïng. Ta khoâng theå taïo ñoái töôïng thuoäc lôùp cô sôû thuaàn tuyù.
(cid:1) Ta coù theå ñònh nghóa phöông thöùc aûo thuaàn tuyù, nhöng chæ
coù caùc ñoái töôïng thuoäc lôùp con coù theå goïi noù.
(cid:1) Phöông thöùc aûo thuaàn tuyù coù yù nghóa cho vieäc toå chöùc sô ñoà phaân caáp caùc lôùp, noù ñoùng vai troø chöøa saün choã troáng cho phaân caáp caùc lôùp, noù ñoùng vai troø chöøa saün choã troáng cho caùc lôùp con ñieàn vaøo vôùi phieân baûn phuø hôïp.
22
Phöông thöùc aûo thuaàn tuyù vaø lôùp cô sôû tröøu töôïng Phöông thöùc aûo thuaàn tuyù vaø lôùp cô sôû tröøu töôïng
(cid:1) Baûn thaân caùc lôùp con cuûa lôùp cô sôû tröøu töôïng cuõng coù theå
laø lôùp cô sôû tröøu töôïng.
23