BÀI 5:
TÍNH ĐA HÌNH
(Polymorphism)
1. Khái nim
Phương thc ca lp cha khi thc hin s được thay thế bng mt phương thc ca lp con thì
phương thc này gi là có tính đa hình. Tính đa hình giúp cho vic lp trình đơn gin và d m rng.
Để cài đặt phương thc có tính đa hình ta dùng phương thc o và phương thc thun o.
2. Phương thc o (virtual method)
Phương thc o là phương thc được định nghĩa lp cơ s (lp cha) mà các lp dn xut (lp con)
mun s dng phi định nghĩa li. Dùng t khoá virtual để khai báo phương thc o:
virtual <kiu tr v> <tên phương thc >(<d/s tham s>)
{…}
Phương thc khi to không được là phương thc o nhưng phương thc hy b có th là phương
thc o. Dùng phương thc o chm hơn phương thc thông thường vì khi thc hin mi được xác
định c th.
Ví d:
#include <iostream.h>
class A
{
public:
virtual void chao() //phương thc o
{
cout<<"\nA chao cac ban";
}
};
class B:public A
{
public:
void chao()
{
cout<<"\nB chao cac ban";
1
}
};
class C:public A
{
public:
void chao()
{
cout<<"\nC chao cac ban";
}
};
void main()
{
A a;
A *pa= new A; pa->chao(); //goi chao cua A
B b;
pa=&b; pa->chao(); //goi chao cua B
C c;
pa=&c; pa->chao(); //goi chao cua C
}
Nhn xét:
-Phương thc chao() có tính đa hình: cùng li gi pa->chao() nhưng ln 1 gi chao cua A, lan 2
gi chao cua B, lan 3 goi chao cua C.
-Nếu trong lp B, C không định nghĩa li phương thc chào thì c ba ln đều gi chào ca A.
-Nếu phương thc chao() trong lp A không khai báo virtual thì phương thc chao() s không có
tính đa hình, khi đó c ba ln đều gi chào ca A.
-Có th gán địa ch ca đt thuc lp con vào biến con tr, tr ti đt thuc lp cha nhưng không
th làm ngược li (áp dng nguyên tc “con gán vào cha” đối vi biến kiu đối tượng hoc
biến kiu con tr, tr ti đối tượng)
3. Phương thc thun o, lp tru tượng
Phương thc thun o là phương thc o nhưng không có lnh (phương thc rng). Phương thc
thun o có dng:
virtual <kiu tr v> <tên phương thc >(<d/s tham s>) = 0;
2
Lp có phương thc o gi là lp tru tượng (abstract class). Nếu mt lp tha kế lp tru tượng mà
không định nghĩa li phương thc thun o thì lp tha kế cũng là lp tru tượng. Lưu ý là không được
to đối tượng thuc lp tru tượng.
Thường ta chn phương thc lp cha, mà chưa th xác định cách thc hin, làm phương thc thun
o. lp con ta s định nghĩa li phương thc thun o, để xác định c th cách thc thc hin.
Ví d:
Nhp mt danh sách gm ging viên và sinh viên, in ra danh sách nhng người được thưởng. Biết
rng điu kin được thưởng là ging viên có s bài báo >3, sinh vien có đim thi tt nghip >8.
#include <iostream.h>
class nguoi
{
char hoten[30];
public:
virtual void nhap() //phương thc o
{
cout<<"\nHo ten:"; cin.getline(hoten,30);
}
virtual int thuong()=0; //phương thc thun o
virtual void xuat() //phương thc o
{
cout<<"\nHo ten:"<<hoten;
}
};
class sinhvien:public nguoi
{
float dttn;
public:
void nhap() //đinh nghĩa li phương thc nhp
{
nguoi::nhap();
cout<<"\nDiem thi tn:"; cin>>dttn;
}
int thuong() //đinh nghĩa li phương thc thưởng
{
return (dttn>8?1:0);
}
void xuat() //đinh nghĩa li phương thc xut
3
{
cout<<"\n-Sinh vien:";
nguoi::xuat();
cout<<"\nDiem thi tn:"<<dttn;
}
};
class giangvien:public nguoi
{
int sobaibao;
public:
void nhap()
{
nguoi::nhap();
cout<<"\nSo bai bao:"; cin>>sobaibao;
}
int thuong()
{
return (sobaibao>3?1:0);
}
void xuat()
{
cout<<"\n-Giang vien:";
nguoi::xuat();
cout<<"\nSo bai bao:"<<sobaibao;
}
};
void main()
{
nguoi *ds[100]; int k=0, chon, i;
while(1)
{
cout<<"\n*Gv/Sv/Ngung (1,2,3):"; cin>>chon; cin.get();
if (chon==3) break;
if (chon==1) ds[k]=new giangvien();
if (chon==2) ds[k]=new sinhvien();
ds[k]->nhap(); k++;
}
4
cout<<"\n*Danh sach nhung nguoi duoc thuong";
for (i=0; i<k; i++)
if (ds[i]->thuong()) ds[i]->xuat();
}
Hãy m rng bài tp trên bng cách thêm mt lp nhân viên, biết rng nhân viên có s ngày ngh
trong năm <5 là được thưởng.
Nhn xét:
Do phương thc “nhp, thưởng, xut” là phương thc o ca lp người (lp cha) nên các phương thc
này khi thc thi s có tính đa hình: có khi gi “nhp, thưởng, xut” ca lp ging viên (lp con), có khi
thì gi “nhp, thưởng, xut” ca lp sinh viên (lp con) tu theo con tr ds[i] đang gi địa ch ca đối
tượng ging viên hay sinh viên.
5