Upload
others
View
0
Download
0
Embed Size (px)
Citation preview
3. 3. KeáKeá thöøathöøa
1
3. 3. KeáKeá thöøathöøa
Noäi dungNoäi dung1.1. Môû ñaàuMôû ñaàu2.2. Keá thöøa ñônKeá thöøa ñôn3.3. Phaïm vi truy xuaátPhaïm vi truy xuaát4.4. Phöông thöùc thieát laäp vaø huyû boûPhöông thöùc thieát laäp vaø huyû boû
2
4.4. Phöông thöùc thieát laäp vaø huyû boûPhöông thöùc thieát laäp vaø huyû boû5.5. Con troû vaø keá thöøaCon troû vaø keá thöøa
1 Môû ñaàu1 Môû ñaàu- Söï keá thöøa laø moät ñaëc ñieåm cuûa ngoân ngöõ duøng ñeå bieåu
dieãn moái quan heä ñaëc bieät giöõa caùc lôùp. Caùc lôùp ñöôïc tröøutöôïng hoùa vaø toå chöùc thaønh moät sô ñoà phaân caáp lôùp.
- Keá thöøa laø moät cô cheá tröøu töôïng hoùa. Thuû tuïc vaø haøm laø côcheá tröøu töôïng hoùa cho giaûi thuaät, record vaø struct laø tröøutöôïng hoùa cho döõ lieäu. Khaùi nieäm lôùp trong C++, keát hôïpdöõ lieäu vaø thuû tuïc ñeå ñöôïc kieåu döõ lieäu tröøu töôïng vôùi giao
3
döõ lieäu vaø thuû tuïc ñeå ñöôïc kieåu döõ lieäu tröøu töôïng vôùi giaodieän ñoäc laäp vôùi caøi ñaët vaø cho ngöôøi söû duïng caûm giaùcthoaûi maùi nhö kieåu döõ lieäu coù saün
- Söï keá thöøa laø moät möùc cao hôn cuûa tröøu töôïng hoùa. cungcaáp moät cô cheá gom chung caùc lôùp coù lieân quan vôùi nhauthaønh moät möùc khaùi quaùt hoùa ñaëc tröng cho toaøn boä caùc lôùpnoùi treân. Caùc lôùp vôùi caùc ñaëc ñieåm töông töï nhau coù theåñöôïc toå chöùc thaønh moät sô ñoà phaân caáp keá thöøa. Lôùp ôûtreân cuøng laø tröøu töôïng hoùa cuûa toaøn boä caùc lôùp oû beân döôùinoù.
Môû ñaàuMôû ñaàu� Quan heä laø 1: Keá thöøa ñöôïc söû duïng thoâng duïng nhaát ñeå
bieåu dieãn quan heä laø moät.• Moät sinh vieân laø moät ngöôøi• Moät hình troøn laø moät hình ellipse• Moät tam giaùc laø moät ña giaùc
� Keá thöøa taïo khaû naêng xaây döïng lôùp môùi töø lôùp ñaõ coù, trong ñoù haøm thaønh phaàn ñöôïc thöøa höôûng töø lôùp cha. Trong
4
ñoù haøm thaønh phaàn ñöôïc thöøa höôûng töø lôùp cha. Trong C++, keá thöøa coøn ñònh nghóa söï töông thích, nhôø ñoù ta coù cô cheá chuyeån kieåu töï ñoäng.
� Keá thöøa vöøa coù khaû naêng taïo cô cheá khaùi quaùt hoaù vöøa coù khaû naêng chuyeân bieät hoaù.
� Keá thöøa cho pheùp toå chöùc caùc lôùp chia seû maõ chöông trình chung nhôø vaäy coù theå deã daøng söûa chöõa, naâng caáp heä thoáng.
Môû ñaàuMôû ñaàu� Keá thöøa thöôøng ñöôïc duøng theo hai caùch:
• Ñeå phaûn aùnh moái quan heä giöõa caùc lôùp. Laø coâng cuï ñeå toå chöùc vaø phaân caáp lôùp döïa vaøo söï chuyeân bieät hoùa, trong ñoù moät vaøi haøm thaønh phaàn cuûa lôùp con laø phieân baûn hoaøn thieän hoaëc ñaëc bieät hoaù cuûa phieân baûn ôû lôùp cha. Trong C++ moái quan heä naøy thöôøng ñöôïc caøi ñaët söû duïng:
5
söû duïng:� Keá thöøa public.� Haøm thaønh phaàn laø phöông thöùc aûo
• Ñeå phaûn aùnh söï chia seû maõ chöông trình giöõa caùc lôùp khoâng coù quan heä veà maët ngöõ nghóa nhöng coù theå coù toå chöùc döõ lieäu vaø maõ chöông trình töông töï nhau. Trong C++, cô cheá chia seû maõ naøy thöôøng ñöôïc caøi ñaët duøng:� Keá thöøa private.� Haøm thaønh phaàn khoâng laø phöông thöùc aûo.
2 Keá thöøa ñôn2 Keá thöøa ñôn� Keá thöøa coù theå ñöôïc thöïc hieän ñeå theå hieän moái quan heä 'laø
moät'.� Xeùt hai khaùi nieäm ngöôøi vaø sinh vieân vôùi moái quan heä töï
nhieân: moät 'sinh vieân' laø moät 'ngöôøi'. Trong C++, ta coù theåbieåu dieãn khaùi nieäm treân, moät sinh vieân laø moät ngöôøi coùtheâm moät soá thoâng tin vaø moät soá thao taùc (rieâng bieät cuûasinh vieân).
6
sinh vieân).� Ta toå chöùc lôùp sinh vieân keá thöøa töø lôùp ngöôøi. Lôùp ngöôøi
ñöôïc goïi laø lôùp cha (superclass) hay lôùp cô sôû (base class).Lôùp sinh vieân ñöôïc goïi laø lôùp con (subclass) hay lôùp daãnxuaát (derived class).
Keá thöøa ñônKeá thöøa ñônclass Nguoi
{
friend class SinhVien;
char *HoTen;
int NamSinh;
public:
Nguoi(char *ht, int ns):NamSinh(ns) {HoTen =
strdup(ht);}
7
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;
friend ostream& operator << (ostream &os,
Nguoi& p);
};
Keá thöøa ñônKeá thöøa ñônclass SinhVien : public Nguoi
{
char *MaSo;
public:
SinhVien(char *ht, char *ms, int ns) :
Nguoi(ht,ns) { MaSo = strdup(ms);}
~SinhVien() {delete [] MaSo;}
void Xuat() const;
8
void Xuat() const;
};
ostream& operator << (ostream &os, Nguoi& p)
{
return os << "Nguoi, ho ten: " << p.HoTen << "
sinh " << p.NamSinh;
}
Keá thöøa ñônKeá thöøa ñônvoid Nguoi::Xuat() const
{
cout << "Nguoi, ho ten: " << HoTen << " sinh "
<< NamSinh;
}
void SinhVien::Xuat() const
{
9
{
cout << "Sinh vien, ma so: " << MaSo << ", ho
ten: " << HoTen;
}
Keá thöøa ñônKeá thöøa ñônvoid main()
{
Nguoi p1("Le Van Nhan",1980);
SinhVien s1("Vo Vien Sinh", "200002541",1984);
cout << ”1.\n";
p1.An(); cout << "\n";
s1.An();cout << "\n";
10
s1.An();cout << "\n";
cout << ”2.\n";
p1.Xuat(); cout << "\n";
s1.Xuat(); cout << "\n";
s1.Nguoi::Xuat(); cout << "\n";
cout << "3.\n";
cout << p1 << "\n";
cout << s1 << "\n";
}
Töï ñoäng keá thöøa caùc ñaëc tính cuûa lôùp chaTöï ñoäng keá thöøa caùc ñaëc tính cuûa lôùp cha
� Khai baùo class SinhVien : public Nguoi
{
//...
};
Cho bieát lôùp sinh vieân keá thöøa töø lôùp ngöôøi. Khi ñoù sinh vieân ñöôïc thöøa höôûng caùc ñaëc tính cuûa lôùp ngöôøi.
11
vieân ñöôïc thöøa höôûng caùc ñaëc tính cuûa lôùp ngöôøi.� Veà maët döõ lieäu: Moãi ñoái töôïng sinh vieân töï ñoäng coù thaønh
phaàn döõ lieäu hoï teân vaø naêm sinh cuûa ngöôøi.� Veà maët thao taùc: Lôùp sinh vieân ñöôïc töï ñoäng keá thöøa caùc
thao taùc cuûa lôùp cha. Ñaây chính laø khaû naêng söû duïng laïi maõ chöông trình.
� Rieâng phöông thöùc thieát laäp khoâng ñöôïc keá thöøa.
Töï ñoäng keá thöøa caùc ñaëc tính cuûa lôùp chaTöï ñoäng keá thöøa caùc ñaëc tính cuûa lôùp cha
Nguoi p1("Le Van Nhan",1980);
SinhVien s1("Vo Vien Sinh", "200002541",1984);
p1.An(); cout << "\n";
s1.An();cout << "\n"; // Tu lop Nguoi
p1.Xuat(); cout << "\n";
12
p1.Xuat(); cout << "\n";
� Keá thöøa public nhö treân haøm yù raèng moät ñoái töôïng sinh vieân laø moät ñoái töôïng ngöôøi. Nôi naøo chôø ñôïi moät ñoái töôïng ngöôøi coù theå ñöa vaøo ñoù moät ñoái töôïng sinh vieân (c/kieåu).
� Khaû naêng thöøa höôûng caùc thao taùc cuûa lôùp cô sôû coù theå ñöôïc truyeàn qua voâ haïn möùc.
Ñònh nghóa laïi thao taùc ôû lôùp conÑònh nghóa laïi thao taùc ôû lôùp con� Ta coù theå ñònh nghóa laïi caùc ñaëc tính ôû lôùp con ñaõ coù ôû lôùp
cha, vieäc ñònh nghóa chuû yeáu laø thao taùc, baèng caùch khai baùo gioáng heät nhö ôû lôùp cha.class SinhVien : public Nguoi
{
char *MaSo;
public:
//...
13
//...
void Xuat() const;
};
void SinhVien::Xuat() const
{
cout << "Sinh vien, ma so: " << MaSo << ", ho
ten: " << HoTen;
}
� Vieäc ñònh nghóa laïi thao taùc ôû lôùp con ñöôïc thöïc hieän khi thao taùc ôû lôùp con khaùc thao taùc ôû lôùp cha. Thoâng thöôøng laø caùc thao taùc xuaát, nhaäp.
� Ta cuõng coù theå ñònh nghóa laïi thao taùc ôû lôùp con trong tröôøng hôïp giaûi thuaät ôû lôùp con ñôn giaûn hôn (toâ maøu ña giaùc, tính modun cuûa soá aûo...).class DaGiac
Ñònh nghóa laïi thao taùc ôû lôùp conÑònh nghóa laïi thao taùc ôû lôùp con
14
class DaGiac
{
// ...
void Ve() const;
void ToMau() const;
};
class HCN
{
void ToMau() const;
};
Ñònh nghóa laïi thao taùc ôû lôùp conÑònh nghóa laïi thao taùc ôû lôùp con� Hoaëc ôû lôùp con, thao taùc khoâng coù taùc duïng
class Ellipse
{
//...
public:
//...
void rotate(double rotangle){ //...}
};
15
};
class Circle:public Ellipse
{
public:
//...
void rotate(double rotangle){/* do nothing */}
};
3 Raøng buoäc ngöõ nghóa ôû lôùp con3 Raøng buoäc ngöõ nghóa ôû lôùp con� Keá thöøa coù theå ñöôïc aùp duïng cho quan heä keá thöøa mang yù
nghóa raøng buoäc, ñoái töôïng ôû lôùp con laø ñoái töôïng ôû lôùp cha nhöng coù döõ lieäu bò raøng buoäc.• Hình troøn laø Ellipse raøng buoäc baùn kính ngang doïc baèng
nhau.• Soá aûo laø soá phöùc raøng buoäc phaàn thöïc baèng 0.• Hình vuoâng laø hình chöõ nhaät raøng buoäc hai caïnh ngang
16
• Hình vuoâng laø hình chöõ nhaät raøng buoäc hai caïnh ngang vaø doïc baèng nhau…
� Trong tröôøng hôïp naøy, caùc haøm thaønh phaàn phaûi baûo ñaûm söï raøng buoäc döõ lieäu ñöôïc toân troïng. Lôùp soá aûo sau ñaây laø moät ví duï minh hoaï.
Raøng buoäc ngöõ nghóa ôû lôùp conRaøng buoäc ngöõ nghóa ôû lôùp conclass Complex
{
friend ostream& operator <<(ostream&, Complex);
friend class Imag;
double re, im;
public:
Complex(double r = 0, double i = 0):re(r),
im(i){}
17
im(i){}
Complex operator +(Complex b);
Complex operator -(Complex b);
Complex operator *(Complex b);
Complex operator /(Complex b);
double Norm() const {return sqrt(re*re +
im*im);}
};
class Imag: public Complex
{
public:
Imag(double i = 0):Complex(0, i){}
Imag(const Complex &c) : Complex(0, c.im){}
Imag& operator = (const Complex &c)
{re = 0; im = c.im; return *this;}
double Norm() const {return fabs(im);}
};
Raøng buoäc ngöõ nghóa ôû lôùp conRaøng buoäc ngöõ nghóa ôû lôùp con
18
};
void main()
{
Imag i = 1;
Complex z1(1,1), z3 = z1 - i; // z3 = (1,0)
i = Complex(5,2); // i la so ao (0,2)
Imag j = z1; // j la so ao (0,1)
cout << "z1 = " << z1 << "\n";
cout << "i = " << i << "\n";
cout << "j = " << j << "\n";
}
Raøng buoäc ngöõ nghóa ôû lôùp conRaøng buoäc ngöõ nghóa ôû lôùp con� Trong ví duï treân lôùp soá aûo (Imag) keá thöøa haàu heát caùc thao
taùc cuûa lôùp soá phöùc (Complex). Tuy nhieân ta muoán raøng buoäc moïi ñoái töôïng thuoäc lôùp soá aûo ñeàu phaûi coù phaàn thöïc baèng 0. Vì vaäy phaûi ñònh nghóa laïi caùc haøm thaønh phaàn coù theå vi phaïm ñieàu naøy. Ví duï pheùp toaùn gaùn phaûi ñöôïc ñònh nghóa laïi ñeå baûo ñaûm raøng buoäc naøy.class Imag: public Complex
19
class Imag: public Complex
{
public:
//...
Imag(const Complex &c) : Complex(0, c.im){}
Imag& operator = (const Complex &c)
{re = 0; im = c.im; return *this;}
};
Raøng buoäc ngöõ nghóa ôû lôùp conRaøng buoäc ngöõ nghóa ôû lôùp con� Ví duï sau minh hoaï theâm raøng buoäc ngöõ nghóa ôû lôùp con
class HCN:public Hinh
{
friend class HV;
Diem TrenTrai;
double rong, cao;
public:
HCN(Diem tt, double r, double c);
20
HCN(Diem tt, double r, double c);
HCN(double ttx, double tty, double r, double c);
HCN():TrenTrai(4,6), rong(7), cao(4){}
double DienTich() const {return rong*cao;}
void Nhap() {cin >> TrenTrai >> rong >> cao;}
void Xuat();
void PhongTo(double tiLe);
void GianNgang(double tiLe);
void GianDoc(double tiLe);
};
Raøng buoäc ngöõ nghóa ôû lôùp conRaøng buoäc ngöõ nghóa ôû lôùp convoid HCN::PhongTo(double tiLe)
{
rong *= tiLe;
cao *= tiLe;
}
void HCN::GianNgang(double tiLe)
{
TrenTrai.TinhTien(rong*(1-tiLe)/2, 0);
21
TrenTrai.TinhTien(rong*(1-tiLe)/2, 0);
rong *= tiLe;
}
void HCN::GianDoc(double tiLe)
{
TrenTrai.TinhTien(0, cao*(1-tiLe)/2);
cao *= tiLe;
}
void Nhap();
Raøng buoäc ngöõ nghóa ôû lôùp conRaøng buoäc ngöõ nghóa ôû lôùp conclass HV:public HCN
{
public:
HV(Diem tt, double canh):HCN(tt, canh, canh){}
HV(double ttx, double tty, double
canh):HCN(ttx,tty,canh,canh){}
HV():HCN(7,8,6,6){}
char *TenLop() {return "Hinh Vuong";}
22
char *TenLop() {return "Hinh Vuong";}
void Nhap() {cin >> TrenTrai >> rong; cao = rong;}
void Xuat();
void GianNgang(double tiLe);
void GianDoc(double tiLe);
};
Raøng buoäc ngöõ nghóa ôû lôùp conRaøng buoäc ngöõ nghóa ôû lôùp convoid HV::GianNgang(double tiLe)
{
PhongTo(sqrt(tiLe));
}
void HV::GianDoc(double tiLe)
{
PhongTo(sqrt(tiLe));
23
PhongTo(sqrt(tiLe));
}
4 Phaïm vi truy xuaát4 Phaïm vi truy xuaát� Khi thieát laäp quan heä keá thöøa, ta vaãn phaûi quan taâm ñeán
tính ñoùng goùi vaø che daáu thoâng tin. Ñieàu naøy daãn ñeán vaán ñeà xaùc ñònh aûnh höôûng cuûa keá thöøa ñeán phaïm vi truy xuaát caùc thaønh phaàn cuûa lôùp. Hai vaán ñeà ñöôïc ñaët ra laø:
� Truy xuaát theo chieàu doïc: Haøm thaønh phaàn cuûa lôùp con coù quyeàn truy xuaát caùc thaønh phaàn rieâng tö cuûa lôùp cha hay khoâng ? Vì chieàu truy xuaát laø töø lôùp con, chaùu leân lôùp cha
24
khoâng ? Vì chieàu truy xuaát laø töø lôùp con, chaùu leân lôùp cha neân ta goïi laø truy xuaát theo chieàu doïc
� Truy xuaát theo chieàu ngang: Caùc thaønh phaàn cuûa lôùp cha, sau khi keá thöøa xuoáng lôùp con, thì theá giôùi beân ngoaøi coù quyeàn truy xuaát thoâng qua ñoái töôïng cuûa lôùp con hay khoâng? Trong tröôøng hôïp naøy, ta goïi laø truy xuaát theo chieàu ngang.
4.1 Truy xuaát theo chieàu doïc4.1 Truy xuaát theo chieàu doïc� Lôùp con coù quyeàn truy xuaát caùc thaønh phaàn cuûa lôùp cha
hay khoâng, hay toång quaùt hôn, nôi naøo coù quyeàn truy xuaát caùc thaønh phaàn cuûa lôùp cha, hoaøn toaøn do lôùp cha quyeát ñònh. Ñieàu ñoù ñöôïc xaùc ñònh baèng thuoäc tính truy xuaát .
� Trong tröôøng hôïp lôùp sinh vieân keá thöøa töø lôùp ngöôøi, truy xuaát theo chieàu doïc coù nghóa lieäu lôùp sinh vieân coù quyeàn truy xuaát caùc thaønh phaàn hoï teân, naêm sinh cuûa lôùp ngöôøi
25
truy xuaát caùc thaønh phaàn hoï teân, naêm sinh cuûa lôùp ngöôøi hay khoâng. Chính xaùc hôn moät ñoái töôïng sinh vieân coù quyeàn truy xuaát hoï teân cuûa chính mình nhöng ñöôïc khai baùo ôû lôùp ngöôøi hay khoâng?
� Thuoäc tính truy xuaát laø ñaëc tính cuûa moät thaønh phaàn cuûa lôùp cho bieát nhöõng nôi naøo coù quyeàn truy xuaát thaønh phaàn ñoù.
Thuoäc tính truy xuaátThuoäc tính truy xuaát� Thuoäc tính public: Thaønh phaàn naøo coù thuoäc tính public thì
coù theå ñöôïc truy xuaát töø baát cöù nôi naøo (töø sau khai baùo lôùp).
� Thuoäc tính private: Thaønh phaàn naøo coù thuoäc tính private thì noù laø rieâng tö cuûa lôùp ñoù. Chæ coù caùc haøm thaønh phaàn cuûa lôùp vaø ngoaïi leä laø caùc haøm baïn ñöôïc pheùp truy xuaát, ngay caû caùc lôùp con cuõng khoâng coù quyeàn truy xuaát.
26
ngay caû caùc lôùp con cuõng khoâng coù quyeàn truy xuaát.
Thuoäc tính truy xuaátThuoäc tính truy xuaátclass Nguoi
{
char *HoTen;
int NamSinh;
public:
//...
};
class SinhVien : public Nguoi
27
class SinhVien : public Nguoi
{
char *MaSo;
public:
//...
void Xuat() const; // khong the truy xuat
}; // Nguoi::HoTen va Nguoi::NamSinh
Thuoäc tính privateThuoäc tính private� Trong ví duï treân, khoâng coù haøm thaønh phaàn naøo cuûa lôùp
SinhVien coù theå truy xuaát caùc thaønh phaàn private HoTen, NamSinh cuûa lôùp Nguoi. Noùi caùch khaùc, lôùp con khoâng coù quyeàn vi phaïm tính ñoùng goùi cuûa lôùp cha. Ñoaïn chöông trình sau gaây ra loãi luùc bieân dòch.void SinhVien::Xuat() const
{
28
{
cout << "Sinh vien, ma so: " << MaSo << ", ho
ten: " << HoTen;
}
� Ta coù theå khaéc phuïc ñöôïc loãi treân nhôø khai baùo lôùp SinhVien laø baïn cuûa lôùp Nguoi, nhö trong ví duï ôû ñaàu chöông:
Thuoäc tính privateThuoäc tính privateclass Nguoi
{
friend class SinhVien;
char *HoTen;
int NamSinh;
public:
//...
};
class SinhVien : public Nguoi
29
class SinhVien : public Nguoi
{
char *MaSo;
public:
//...
void Xuat() const { cout << "Sinh vien, ma so: "
<< MaSo << ", ho ten: " << HoTen; }
};
Thuoäc tính privateThuoäc tính private� Vôùi khai baùo haøm baïn nhö treân, lôùp sinh vieân coù theå truy
xuaát caùc thaønh phaàn cuûa lôùp ngöôøi.void SinhVien::Xuat() const
{
cout << "Sinh vien, ma so: " << MaSo << ", ho
ten: " << HoTen; // Ok: co quyen truy xuat
// Nguoi::HoTen, Nguoi::NamSinh
}
30
}
� Caùch laøm treân giaûi quyeát ñöôïc nhu caàu cuûa ngöôøi söû duïng khi muoán taïo lôùp con coù quyeàn truy xuaát caùc thaønh phaàn döõ lieäu private cuûa lôùp cha. Tuy nhieân noù ñoøi hoûi phaûi söûa ñoåi laïi lôùp cha vaø taát caû caùc lôùp ôû caáp cao hôn moãi khi moät lôùp con môùi ra ñôøi.
Thuoäc tính privateThuoäc tính privateclass Nguoi
{
friend class SinhVien;
friend class NuSinh;
char *HoTen;
int NamSinh;
public:
//...
31
//...
void An() const { cout << HoTen << " an 3 chen
com";}
};
class SinhVien : public Nguoi
{
friend class NuSinh;
char *MaSo;
public:
//...
};
Thuoäc tính privateThuoäc tính privateclass NuSinh : public SinhVien
{
public:
NuSinh(char *ht, char *ms, int ns) :
SinhVien(ht,ms,ns) {}
void An() const { cout << HoTen << " ma so "
<< MaSo << " an 2 to pho";}
};
32
};
void main()
{
Nguoi p1("Le Van Nhan",1980);
SinhVien s1("Vo Vien Sinh", "200002541",1984);
NuSinh ns("Le Thi Ha Dong", "200002544",1984);
p1.An(); cout << "\n";
s1.An();cout << "\n";
ns.An();cout << "\n";
}
Thuoäc tính protectedThuoäc tính protected� Trong ví duï treân, khi lôùp NuSinh ra ñôøi ta phaûi thay ñoåi lôùp
cha SinhVien vaø caû lôùp cô sôû Nguoi ôû möùc cao hôn.� Thuoäc tính protected: cho pheùp qui ñònh moät vaøi thaønh
phaàn naøo ñoù cuûa lôùp laø baûo maät, theo nghóa theá giôùi beân ngoaøi khoâng ñöôïc pheùp truy xuaát, nhöng taát caû caùc lôùp con, chaùu… ñeàu ñöôïc pheùp truy xuaátclass Nguoi
33
class Nguoi
{
protected:
char *HoTen;
int NamSinh;
public:
//...
};
Thuoäc tính protectedThuoäc tính protectedclass SinhVien : public Nguoi
{
protected:
char *MaSo;
public:
SinhVien(char *ht, char *ms, int ns) :
Nguoi(ht,ns) { MaSo = strdup(ms);}
~SinhVien() {delete [] MaSo;}
34
~SinhVien() {delete [] MaSo;}
void Xuat() const; // Co the truy xuat
// Nguoi::HoTen va Nguoi::NamSinh
};
Thuoäc tính protectedThuoäc tính protectedclass NuSinh : public SinhVien
{
public:
NuSinh(char *ht, char *ms, int ns) :
SinhVien(ht,ms,ns) {}
void An() const { cout << HoTen << " ma so "
<< MaSo << " an 2 to pho";}
}; // Co the truy xuat Nguoi::HoTen va
35
}; // Co the truy xuat Nguoi::HoTen va
// Nguoi::NamSinh va SinhVien::MaSo
Thuoäc tính protectedThuoäc tính protectedvoid Nguoi::Xuat() const
{
cout << "Nguoi, ho ten: " << HoTen << " sinh "
<< NamSinh;
}
void SinhVien::Xuat() const
{
36
{
cout << "Sinh vien, ma so: " << MaSo << ", ho
ten: " << HoTen; // Ok: co quyen truy xuat
// Nguoi::HoTen, Nguoi::NamSinh
}
Thuoäc tính protectedThuoäc tính protected� Thuoäc tính protected laø phöông tieän ñeå traùnh phaûi söûa ñoåi
lôùp cô sôû khi coù lôùp con môùi ra ñôøi. Nhôø ñoù noù baûo ñöôïc tính ñoùng cuûa moät lôùp. Khai baùo moät thaønh phaàn naøo coù thuoäc tính protected töông ñöông vôùi qui ñònh tröôùc taát caû caùc lôùp con, chaùu sau naøy ñeàu laø baïn cuûa thaønh phaàn ñoù.
� Thoâng thöôøng ta duøng thuoäc tính protected cho caùc thaønh phaàn döõ lieäu vaø thuoäc tính public cho haøm thaønh phaàn.
37
phaàn döõ lieäu vaø thuoäc tính public cho haøm thaønh phaàn.� Caùc thuoäc tính public, private, protected vaø khai baùo friend
cho nhöõng nôi naøo coù quyeàn truy xuaát ñeán caùc thaønh phaàn cuûa lôùp. Cho hay khoâng cho ai truy xuaát ñeán (thaønh phaàn cuûa) lôùp hoaøn toaøn do lôùp quyeát ñònh.
4.2 Truy xuaát theo chieàu ngang4.2 Truy xuaát theo chieàu ngang� Thaønh phaàn protected vaø public cuûa lôùp khi ñaõ keá thöøa
xuoáng lôùp con thì theá giôùi beân ngoaøi coù quyeàn truy xuaát thoâng qua ñoái töôïng thuoäc lôùp con hay khoâng? Ñieàu naøy hoaøn toaøn do lôùp con quyeát ñònh baèng thuoäc tính keá thöøa. Coù hai thuoäc tính keá thöøa laø keá thöøa public vaø keá thöøa private.
� Keá thöøa public: Lôùp con keá thöøa public töø lôùp cha thì caùc
38
� Keá thöøa public: Lôùp con keá thöøa public töø lôùp cha thì caùc thaønh phaàn protected cuûa lôùp cha trôû thaønh protected cuûa lôùp con, caùc thaønh phaàn public cuûa lôùp cha trôû thaønh public cuûa lôùp con. Noùi caùch khaùc moïi thao taùc cuûa lôùp cha ñöôïc keá thöøa xuoáng lôùp con. Vì vaäy ta coù theå söû duïng thao taùc cuûa lôùp cha cho ñoái töôïng thuoäc lôùp con.
� Ta qui ñònh keá thöøa public baèng töø khoaù public theo sau daáu hai chaám khi thieát laäp quan heä keá thöøa.
Keá thöøa publicKeá thöøa publicclass SinhVien : public Nguoi
{
char *MaSo;
public:
SinhVien(char *ht, char *ms, int ns) :
Nguoi(ht,ns) { MaSo = strdup(ms);}
~SinhVien() {delete [] MaSo;}
void Xuat() const;
39
void Xuat() const;
};
� Khai baùo nhö treân cho bieát moïi thao taùc (public) cuûa lôùp ngöôøi ñeàu aùp ñöôïc cho moïi ñoái töôïng sinh vieân.//...
SinhVien s1("Vo Vien Sinh", "200002541",1984);
s1.An();cout << "\n";
s1.Xuat(); cout << "\n";
s1.Nguoi::Xuat(); cout << "\n";
//...
Keá thöøa publicKeá thöøa public� Do ñöôïc thöøa höôûng caùc ñaëc tính cuûa lôùp cha neân ta duøng
keá thöøa public khi vaø chæ khi coù quan heä laø moät töø lôùp con ñeán lôùp cha.
� Haàu heát caùc tröôøng hôïp keá thöøa laø keá thöøa public, noù cho pheùp taän duïng laïi maõ chöông trình, ñoàng thôøi taïo khaû naêng thu gom caùc ñaëc ñieåm chung cuûa caùc lôùp vaøo moät lôùp cô sôû, nhôø ñoù deã daøng naâng caáp vaø söûa chöõa (baûo trì).
40
sôû, nhôø ñoù deã daøng naâng caáp vaø söûa chöõa (baûo trì).
Keá thöøa privateKeá thöøa private� Coù nhöõng tröôøng hôïp caùc lôùp khoâng coù quan heä vôùi nhau
veà maët ngöõ nghóa nhöng chia seû chung chi tieát caøi ñaët, neáu duøng keá thöøa public thì sai khaùi nieäm vì lôùp con seõ thöøa höôûng caùc thao taùc noù khoâng coù töø lôùp cha.
� Keá thöøa private: Lôùp con keá thöøa private töø lôùp cha thì caùc thaønh phaàn protected vaø public cuûa lôùp cha trôû thaønh private cuûa lôùp con. Noùi caùch khaùc moïi thao taùc cuûa lôùp
41
private cuûa lôùp con. Noùi caùch khaùc moïi thao taùc cuûa lôùp cha ñeàu bò lôùp con che daáu. Vì vaäy treân quan ñieåm cuûa theá giôùi beân ngoaøi lôùp con khoâng coù caùc thao taùc maø lôùp cha coù.
� Söû duïng keá thöøa private. Ta coù theå chia seû maõ chöông trình giöõa caùc lôùp coù caáu truùc döõ lieäu töông töï nhau nhöng vaãn giöõ ñöôïc tinh thaàn cuûa töøng lôùp.
Keá thöøa privateKeá thöøa private� Ví duï sau minh hoaï keá thöøa private: Lôùp List bieåu dieãn
khaùi nieäm danh saùch lieân keát, lôùp Stack bieåu dieãn , lôùp Set bieåu dieãn khaùi nieäm taäp hôïp. Neáu toå chöùc Stack, Set nhö danh saùch lieân keát, coù theå duøng keá thöøa private ñeå taän duïng maõ chöông trình chung.typedef int Item;
typedef int bool;
42
typedef int bool;
const bool true = 1, false = 0;
class Link
{
friend class List;
friend class ListIterator;
Link *next;
Item e;
Link(Item a, Link *p):e(a) {next = p;}
};
Keá thöøa privateKeá thöøa privateclass List
{
friend class ListIterator;
Link *last;
public:
List() {last = NULL;}
~List() { CleanUp(); }
void Insert(Item a); // add at head of list
43
void Insert(Item a); // add at head of list
void Append(Item a); // add at tail of list
void GetFirst(Item *px); // return and remove head
void CleanUp();
bool Empty() const {return last == NULL;}
bool IsMember(Item x) const;
int Count() const;
void View() const;
};
Keá thöøa privateKeá thöøa privateclass Stack:private List
{
public:
Stack():List() {}
bool Empty() const {return List::Empty();}
bool Push(Item x) {Insert(x); return true;}
bool Pop(Item *px);
};
44
};
inline bool Stack::Pop(Item *px)
{
if (Empty()) return false;
GetFirst(px);
return true;
}
Keá thöøa privateKeá thöøa privateclass Set:private List
{
public:
Set():List(){}
void Add(Item x) {if (!List::IsMember(x))
Insert(x);}
bool Empty() const {return List::Empty();}
bool IsMember(Item x) const {return
45
bool IsMember(Item x) const {return
List::IsMember(x);}
int Count() const {return List::Count();}
void View() const {List::View();}
};
� Caùc lôùp Stack vaø Set taän duïng ñöôïc caáu truùc döõ lieäu vaø chi tieát caøi ñaët cuûa lôùp List, nhöng khoâng bò trôû thaønh List vì söû duïng keá thöøa private. Caùc thao taùc cuûa List khoâng bò keá thöøa xuoáng lôùp con Stack vaø Set.
Keá thöøa privateKeá thöøa private� Moät soá haøm thaønh phaàn cuûa lôùp cô sôû List coù theå caàn thieát
ôû lôùp con nhö haøm Empty trong lôùp Stack, haøm Empty, IsMember, Count trong lôùp Set… Ta ñònh nghóa laïi nhöõng haøm naøy baèng caùch goïi laïi phieân baûn trong lôùp List.
� Moät caùch thay theá vieäc vieát laïi haøm nhö treân laø khai baùo laïi caùc danh hieäu naøy trong phaàn public cuûa lôùp con. class Stack:private List
46
class Stack:private List
{
public:
Stack():List() {}
bool Push(Item x) {Insert(x); return true;}
bool Pop(Item *px);
List::Empty; // access specifier
};
Keá thöøa privateKeá thöøa private� Ta coù theå laøm töông töï cho lôùp Set.
class Set:private List
{
public:
Set():List(){}
void Add(Item x) {if (!List::IsMember(x))
Insert(x);}
List::Empty; // access specifier
47
List::Empty; // access specifier
List::IsMember;
List::Count;
List::View;
};
� Ta duøng keá thöøa private trong caùc tröôøng hôïp muoán taän duïng maõ chöông trình chung vaø coù theå muoán keá thöøa moät phaàn nhöng khoâng phaûi taát caû caùc thao taùc cuûa lôùp cô sôû.
Keá thöøa privateKeá thöøa privateclass Diem
{
double x,y;
public:
Diem(double xx = 0, double yy = 0):x(xx),y(yy){}
void TinhTien(double dx, double dy);
friend Diem operator + (Diem d);
friend Diem operator - (Diem d);
//...
48
//...
};
class HinhTron:Diem
{
double r;
public:
HinhTron(double tx, double ty, double
rr):Diem(tx,ty),r(rr){}
void Ve(int color) const;
void TinhTien(double dx, double dy) const;
};
Duøng laïi maõ khoâng caàn keá thöøaDuøng laïi maõ khoâng caàn keá thöøa� Ta luoân luoân coù theå taän duïng maõ chöông trình chung baèng
keá thöøa private nhö treân, nhöng cuõng coù theå khoâng caàn duøng keá thöøa.class Link
{
friend class List;
friend class ListIterator;
Link *next;
49
Link *next;
Item e;
Link(Item a, Link *p):e(a) {next = p;}
};
Duøng laïi maõ khoâng caàn keá thöøaDuøng laïi maõ khoâng caàn keá thöøaclass List
{
friend class ListIterator;
Link *last;
public:
void Insert(Item a);
Append(Item a); // add at tail of list
bool GetFirst(Item *);
50
bool GetFirst(Item *);
void CleanUp();
List() {last = NULL;}
List(Item a);
~List() { CleanUp(); }
bool Empty() const {return last == NULL;}
bool IsMember(Item x) const;
int Count() const;
void View() const;
};
Duøng laïi maõ khoâng caàn keá thöøaDuøng laïi maõ khoâng caàn keá thöøaclass Stack
{
List l;
public:
Stack():l() {}
bool Push(Item x) {l.Insert(x); return true;}
bool Pop(Item *px);
bool Empty() const {return l.Empty();}
51
bool Empty() const {return l.Empty();}
};
inline bool Stack::Pop(Item *px)
{
if (l.Empty()) return false;
l.GetFirst(px);
return true;
}
Duøng laïi maõ khoâng caàn keá thöøaDuøng laïi maõ khoâng caàn keá thöøaclass Set
{
List l;
public:
Set():l(){}
void Add(Item x) {if (!l.IsMember(x))
l.Insert(x);}
bool Empty() const {return l.Empty();}
bool IsMember(Item x) const {return
52
bool IsMember(Item x) const {return
l.IsMember(x);}
int Count() const {return l.Count();}
void View() const {l.View();}
};
Duøng laïi maõ khoâng caàn keá thöøaDuøng laïi maõ khoâng caàn keá thöøaclass HinhTron
{
double r;
Diem tam;
public:
HinhTron(double tx, double ty, double
rr):tam(tx,ty),r(rr){}
void Ve(int color) const;
53
void Ve(int color) const;
void TinhTien(double dx, double dy) const;
};
4. Thieát laäp vaø huyû boû4. Thieát laäp vaø huyû boû� Phöông thöùc thieát laäp vaø huyû boû laø caùc haøm thaønh phaàn
ñaëc bieät duøng ñeå töï ñoäng khôûi ñoäng ñoái töôïng khi noù ñöôïc taïo ra vaø töï ñoäng doïn deïp ñoái töôïng khi noù bò huûy ñi.
� Moät ñoái töôïng thuoäc lôùp con coù chöùa caùc thaønh phaàn döõ lieäu cuûa caùc lôùp cô sôû. Coù theå xem lôùp con coù caùc thaønh phaàn ngaàm ñònh öùng vôùi caùc lôùp cô sôû. Vì vaäy khi moät ñoá töôïng thuoäc lôùp con ñöôïc taïo ra, caùc thaønh phaàn cô sôû cuõng
54
töôïng thuoäc lôùp con ñöôïc taïo ra, caùc thaønh phaàn cô sôû cuõng ñöôïc taïo ra, nghóa laø phöông thöùc thieát laäp cuûa caùc lôùp cô sôû phaûi ñöôïc goïi.
� Trình bieân dòch töï ñoäng goïi phöông thöùc thieát laäp cuûa caùc lôùp cô sôû cho caùc ñoái töôïng (cô sôû) nhuùng vaøo ñoái töôïng ñaïng ñöôïc taïo ra.
� Ñoái vôùi phöông thöùc thieát laäp cuûa moät lôùp con, coâng vieäc ñaàu tieân laø goïi phöông thöùc thieát laäp cuûa caùc lôùp cô sôû.
Phöông thöùc thieát laäp vaø huyû boûPhöông thöùc thieát laäp vaø huyû boû� Neáu moïi phöông thöùc thieát laäp cuûa lôùp cô sôû ñeàu ñoøi hoûi
phaûi cung caáp tham soá thì lôùp con baét buoäc phaûi coù phöông thöùc thieát laäp ñeå cung caáp caùc tham soá ñoù.class Diem
{
double x,y;
public:
Diem(double x, double y):x(xx),y(yy){}
55
Diem(double x, double y):x(xx),y(yy){}
//...
};
class HinhTron:Diem
{
double r;
public:
void Ve(int color) const;
};
HinhTron t; // SAI
Cung caáp tham soá thieát laäpCung caáp tham soá thieát laäp� Trong tröôøng hôïp ñoù, lôùp con baét buoäc phaûi coù phöông thöùc
thieát laäp ñeå cung caáp tham soá cho phöông thöùc thieát laäp cuûa lôùp cô sôû.
� Cuù phaùp ñeå goïi phöông thöùc thieát laäp cuûa lôùp cô sôû töông töï nhö cuù phaùp thieát laäp ñoái töôïng thaønh phaàn, baûn thaân teân lôùp cô sôû ñöôïc quan ñieåm nhö ñoái töôïng thaønh phaàn nhuùng vaøo lôùp con.
56
vaøo lôùp con.
Cung caáp tham soá thieát laäpCung caáp tham soá thieát laäpclass HinhTron:Diem
{
double r;
public:
HinhTron(double tx, double ty, double
rr):Diem(tx,ty),r(rr){}
void Ve(int color) const;
void TinhTien(double dx, double dy) const;
57
void TinhTien(double dx, double dy) const;
};
HinhTron t(200,200,50); // Dung
Cung caáp tham soá thieát laäpCung caáp tham soá thieát laäpclass Nguoi
{
protected:
char *HoTen;
int NamSinh;
public:
Nguoi(char *ht, int ns):NamSinh(ns) {HoTen =
strdup(ht);}
//...
58
//...
};
class SinhVien : public Nguoi
{
char *MaSo;
public:
SinhVien(char *ht, char *ms, int ns) :
Nguoi(ht,ns) { MaSo = strdup(ms);}
void Xuat() const;
};
Phöông thöùc thieát laäp vaø huyû boûPhöông thöùc thieát laäp vaø huyû boû� Sau khi phöông thöùc thieát laäp cuûa caùc lôùp cô sôû ñöôïc goïi,
maõ chöông trình trong baûn thaân phöông thöùc cuûa lôùp con seõñöôïc thöïc hieän. Noäi dung cuûa phöông thöùc thieát laäp ôû lôùpcon chæ neân thao taùc treân döõ lieäu cuûa rieâng lôùp con, vieäckhôûi ñoäng döõ lieäu thuoäc lôùp cha do phöông thöùc thieát laäp ôûlôùp cha ñaûm nhieäm vôùi caùc tham soá cung caáp bôûi lôùp con.class SinhVien : public Nguoi
59
class SinhVien : public Nguoi
{
char *MaSo;
public:
SinhVien(char *ht, char *ms, int ns) :
Nguoi(ht,ns) { MaSo = strdup(ms); }
void Xuat() const;
};