Ch y ch y ch ng tr ng tr ình Polymorphism ability occurs only when you use a pointer to an object and used-methods of classes are virtual methods virtual ReturnType or ReturnType virtual
Trang 1L P TRÌNH
VIRTUAL METHOD
& POLYMORPHISM
Tr n Ph c Tu n
tuantp@hcmup.edu.vn http://giaotrinh.tranphuoctuan.com
9/6/2009
N i dung
1. i k t t nh (Static binding)
2. i k t ng (Dynamic binding)
3. Ch y ch ng trình
4. Bài toán th c t
5. Ph ng th c o, a hình
6. Ph ng th c h y b o
7. Ph ng th c thu n o, l p tr u t ng
1 Static binding
class Circle
{ int x,y,r;
public:
Circle (int xx, int yy, int rr)
{ x=xx; y=yy; r=rr;
}
void print()
{ cout <<x<<y<<r;
}
};
void main()
{ Circle c(3,4,5);
c.print();
}
2 Dynamic binding
class Circle { int x,y,r;
public:
Circle (int xx, int yy, int rr) { x=xx; y=yy; r=rr;
} void print() { cout <<x<<y<<r;
} };
void main() { Circle *pc;
pc= new Circle(3,4,5);
pc->print();
}
Trang 2TPTU N - LTH T 5
9/6/2009
3 Ch y ch y ch ng tr ng tr ình
Perhaps, you want
to see “Son”
on the screen.
9/6/2009
3 Ch y ch y ch ng tr ng tr ình
Polymorphism ability occurs only when you use a pointer
to an object and used-methods of classes are virtual methods
virtual ReturnType
or
ReturnType virtual
are accepted
4 Bài toán th c t
Gi ta c n qu n lý m t danh sách các
i t ng có ki u có th khác nhau, ta c n
gi i quy t hai v n
Cách l u tr
Thao tác x lý
Xét tr ng h p c th , các i t ng là
Sinh viên
Công nhân
Nguoi
CongNhan SinhVien
4 Bài toán th c t
Trang 3TPTU N - LTH T 9
9/6/2009
class Nguoi
{
protected:
char *HoTen;
int NamSinh;
public:
Nguoi(char *ht, int ns):NamSinh(ns)
{HoTen = strdup(ht);}
~Nguoi() {delete [] HoTen;}
void Xuat() const
{
cout << "Nguoi, Ho ten: " << HoTen
<< “, Nam Sinh: " << NamSinh;
}
};
9/6/2009
class SinhVien : public Nguoi {
protected:
char *MaSo;
public:
SinhVien(char *n, char *ms, int ns) : Nguoi(n,ns) { MaSo = strdup(ms);}
~SinhVien() {delete [] MaSo;}
void Xuat() const {
cout << "Sinh vien, Ho ten: " << HoTen
<< “, Nam sinh: “ <<NamSinh
<< ", Ma so " << MaSo;
} };
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, Ho ten: " << HoTen
<< “, Nam sinh: “ <<NamSinh
<< “, Muc luong: " << MucLuong;
}
};
4 Bài toán th c t
void XuatDs(int n, Nguoi *an[]) {
for (int i = 0; i < n; i++) {
an[i]->Xuat();
cout << endl;
} }
const int N = 4;
void main(){…… }
Trang 4TPTU N - LTH T 13
9/6/2009
void main()
{
Nguoi *a[N];
a[0] = new SinhVien("Vien Van Sinh",
”200001234", 1982);
a[1] = new SinhVien("Le Thi Ha
Dong",”200001235", 1984);
a[2] = new CongNhan("Tran Nhan Cong",
1000000, 1984);
a[3] = new Nguoi("Nguyen Thanh Nhan",
1960);
XuatDs(4,a);
}
9/6/2009
t qu xu t ra màn hình c a ch ng trình
ng i vì thao tác c th c hi n thông qua con
tr n l p Ng i.
Nguoi, Ho ten: Vien Van Sinh, Sinh Nam: 1982 Nguoi, Ho ten: Le Thi Ha Dong, Sinh Nam: 1984 Nguoi, Ho ten: Tran Nhan Cong, Sinh Nam: 1984 Nguoi, Ho ten: Nguyen Thanh Nhan, Sinh Nam: 1960
Con tr thu c l p c s có th tr n l p con:
Nguoi* pn = new SinhVien(“Le Vien Sinh”, 200001234, 1982);
Ta mong mu n thông qua con tr thu c l p c s
có th truy xu t hàm thành ph n c nh ngh a
i p con:
pn->Xuat(); // Mong muon: goi Xuat cua lop sinh vien,
// thuc te: goi Xuat cua lop Nguoi
Ph ng th c o cho phép gi i quy t v n Ta qui nh m t hàm thành ph n là
ph ng th c o b ng cách thêm t khoá
virtual vào tr c khai báo hàm.
Trong ví d trên, ta thêm t khoá virtual vào tr c khai báo c a hàm xuat.
Trang 5TPTU N - LTH T 17
9/6/2009
class Nguoi
{
protected:
char *HoTen;
int NamSinh;
public:
Nguoi(char *ht, int ns):NamSinh(ns)
{HoTen = strdup(ht);}
~Nguoi() {delete [] HoTen;}
virtual void Xuat() const
{
cout << "Nguoi, Ho ten: " << HoTen
<< “, Nam Sinh: " << NamSinh;
}
};
9/6/2009
class SinhVien : public Nguoi {
protected:
char *MaSo;
public:
SinhVien(char *n, char *ms, int ns) : Nguoi(n,ns) { MaSo = strdup(ms);}
~SinhVien() {delete [] MaSo;}
virtual void Xuat() const {
cout << "Sinh vien, Ho ten: " << HoTen
<< “, Nam sinh: “ <<NamSinh
<< ", Ma so: " << MaSo;
} };
class CongNhan : public Nguoi
{
protected:
double MucLuong;
public:
CongNhan(char *n, double ml, int ns) :
Nguoi(n,ns), MucLuong(ml) { }
virtual void Xuat() const
{
cout << "Cong nhan, Ho ten: " << HoTen
<< “, Nam sinh: “ <<NamSinh
<< “, Muc luong: " << MucLuong;
}
};
void XuatDs(int n, Nguoi *an[]) {
for (int i = 0; i < n; i++) {
an[i]->Xuat();
cout << "\n";
} }
Trang 6TPTU N - LTH T 21
9/6/2009
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, 1984);
a[3] = new Nguoi("Nguyen Thanh Nhan", 1960);
XuatDs(4,a);
}
Ph ng th c o xuat c khai báo p Nguoi cho phép s
ng con tr n l p c s (Nguoi) nh ng tr n m t i
ng thu c l p con (Sinh viên, công nhân) g i úng thao tác
p con:
9/6/2009
5 Ph Ph ng th ng th c o, a hình
Con tr pn thu c l p Nguoi nh ng tr n i
ng sinh viên, vì v y pn->Xuat() th c hi n thao tác xu t c a l p sinh viên.
Tr i ví d trên, khi i a[i] l n l t tr n các
i t ng thu c các lo i khác nhau, thao tác
ng ng v i l p s c g i.
Nguoi *pn;
pn = new SinhVien("Vien Van Sinh“,"200001234“,1982); pn->Xuat(); // Goi thao tac xuat cua lop Sinh vien
class CaSi : public Nguoi
{
protected:
double CatXe;//tien cong cho ca si
public:
CaSi(char *ht, double cx, int ns) : Nguoi(ht,ns),
CatXe(cx) {}
void Xuat() const { cout << "Ca si, " << HoTen <<
" co cat xe " << CatXe;}
};
Dùng ph ng th c o, ta d dàng nâng c p s a ch a.
Vi c thêm m t lo i i t ng m i r t n gi n, ta không c n
ph i s a i thao tác x lý (hàm XuatDs) Qui trình thêm ch
là xây d ng l p con k th a t p c s ho c các l p con ã
có và nh ngh a l i ph ng th c ( o) p m i t o n u c n
void XuatDs(int n, Nguoi *an[]) {
for (int i = 0; i < n; i++) {
an[i]->Xuat();
cout << "\n";
} }
• Hàm XuatDs không thay i, nh ng nó có th ho t ng cho các lo i i t ng ca s thu c l p m i ra i.
• Có th xem nh thao tác XuatDs c vi t tr c cho các l p con cháu ch a ra i.
Trang 7TPTU N - LTH T 25
9/6/2009
5 Ph Ph ng th ng th c o, a hình
Ph ng th c o ch ho t ng thông qua con tr
Mu n m t hàm tr thành ph ng th c o có hai cách:
Khai báo v i t khoá virtual
Hàm t ng ng p c s ã là ph ng th c o.
Ph ng th c o ch ho t ng n u các hàm p c
và l p con có nghi th c giao ti p gi ng h t nhau.
u p con nh ngh a l i ph ng th c o thì s
i ph ng th c p c s (g n nh t có nh
ngh a).
9/6/2009
5 Ph Ph ng th ng th c o, a hình
ch th c hi n c a ph ng th c o
Khi g i m t thao tác, kh ng ch n úng phiên b n
tu theo i t ng th c hi n thông qua con tr
n l p c s c g i là tính a hình (polymorphisms).
ch a hình c th c hi n nh i i t ng
có thêm m t b ng ph ng th c o B ng này ch a
a ch a các ph ng th c o và nó c trình biên
ch kh i t o m t cách ng m nh khi thi t l p i ng.
5 Ph Ph ng th ng th c o, a hình
ch th c hi n ph ng th c o
Khi thao tác c th c hi n thông qua con tr , hàm
có a ch trong b ng ph ng th c o s c g i.
Trong ví d trên, m i i t ng thu c l p c s
Ng i có b ng ph ng th c o có m t ph n t là a
ch hàm Nguoi::Xuat M i i t ng thu c l p
SinhVien có b ng t ng t nh ng n i dung là a ch
a hàm SinhVien::Xuat.
Trang 8TPTU N - LTH T 29
9/6/2009
STUDENT
maso
Name
Id
vtptr
NGUOI
Name
Id
vtptr
Xuat();
Xuat();
9/6/2009
const int N = 4;
void main() {
Nguoi *a[N];
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++) delete a[i];
}
Trong ví d qu n lý danh sách các i t ng thu c các l p Nguoi, SinhVien, CongNhan, … Thao tác d n d p i t ng là
n thi t.
Thông qua con tr thu c l p c s Nguoi,
ch có ph ng th c hu a l p Nguoi
c g i.
o m vi c d n d p là y , ta
dùng ph ng th c hu o.
class Nguoi {
protected:
char *HoTen;
int NamSinh;
public:
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); } };
Trang 9TPTU N - LTH T 33
9/6/2009
Result of so-high generation
class Circle
int x,y,r;
void print()
double area()
double perimeter()
class Rectangle int x1,y1,x2,y2;
void print() double area() double perimeter()
class Triangle int x1,y1,x2,y2,x3,y3;
void print() double area() double perimeter()
class Shape void print() double area() double perimeter()
How will we implement these methods?
Pure virtual
methods
9/6/2009
L p tr u t ng có ít nh t m t ph ng
th c thu n o
Ph ng th c thu n o là ph ng th c
kh ông có ph n thân (ph n nh ngh a)
Cú pháp c a ph ng th c thu n o:
virtual DataType Method (…) = 0;
Con tr này ph i c tr n m t i t ng
a m t l p c th
p c s tr u t ng là l p c s không có i
ng nào thu c chính nó M t i t ng thu c l p
s tr u t ng ph i thu c m t trong các l p con.
Xét các l p Circle, Rectangle, Square k th a t
p Shape
Trong ví d trên, các hàm trong l p Shape có n i
dung nh ng n i dung không có ý ngh a ng th i
ta luôn luôn có th o c i t ng thu c l p
Shape, i u này không úng v i t t ng c a
ph ng pháp lu n h ng i t ng.
Trong ví d trên, các hàm thành ph n trong l p Shape là ph ng th c o thu n tuý Nó b o m không th o c i t ng thu c l p Shape Ví trên c ng nh ngh a n i dung cho ph ng th c
o thu n tuý, nh ng ch có các i t ng thu c l p con có th i.
Ph ng th c o thu n tuý có ý ngh a cho vi c t
ch c s phân c p các l p, nó óng vai trò ch a
n ch tr ng cho các l p con n vào v i phiên
n phù h p.
n thân các l p con c a l p c s tr u t ng
ng có th là l p c s tr u t ng
Trang 10TPTU N - LTH T 37
9/6/2009
Abstract class….
9/6/2009
Abstract subclass
Error: Cannot create instance
of abstract class ‘B’
• A is an abstract class
• B is public subclass of A
• In B, the inherited method MA() is not overriden yet
B is abstract class
Abstract subclass…
Subclass of a concrete class may be an abstract class.
Error: Cannot create instance
of abstract class ‘B’
Demonstration
The following program depicts using abstract class.
People generate all concrete classes as Circle, Rectangle,… into Shape class.
User will input some shape details Program will print out details of all shape Values of area and perimeter of each shape will be printed also.
Trang 11TPTU N - LTH T 41
9/6/2009
Class Shape and Circle
9/6/2009
Class Rectangle
Class ShapeList Class ShapeList…, main(), Result
Trang 12TPTU N - LTH T 45
9/6/2009
Summary
Virtual Method is a way to make polymorphism.
Syntax for virtual method:
virtual ReturnType Method (parameters)
ReturnType virtual Method (parameters)
Compiler will determine the right method will be
called using a virtual function table for every
class which contains virtual methods.
Pure virtual method is a virtual method but it has
no code.
Syntax for pure virtual method:
virtual ReturnType Method (parameters)=0;
9/6/2009
Summary
Abstract class is a result of so-high generation.
Abstract class must have at least one pure virtual method.
You can not create an object of abstract class but you can declare a pointer to it then, it points to an object of a concrete subclass.
Exercises
Using the class Object, implement
classes: Father, Mother, Son, Daughter.
Write a program will
Input a list of members in a family Store them
into a Vector object.
Print out members of the family.