Tài li u
c
Eckel, Bruce. Thinking in C++, 2nd Ed. Vol 1.
L P TRÌNH
NG
IT
NG
K TH A
Chapter 14: Inheritance & Composition
Skip p. 612 (Operator Overloading & Inheritance) to p. 614
(Incremental Development)
Dietel. C++ How to Program, 4th Ed.
Chapter 7: Object-Oriented Programming: Inheritance
Tr n Ph c Tu n
TPT - LTH T
9/6/2009
1. M
N i dung
u
Thu t ng
a quan h
th a k
quan h
i t ng
Object relationship diagram
Cây th a k
inheritance hierarchy
Ví d MotorVehicle
nh ngh a l p MotorVehicle
nh ngh a các l p con
9/6/2009
TPT - LTH T
Quy n truy nh p
Access privilege
Ki u th a k
Cái gì là cái gì?
Các
i t ng
c th a
trong C++
Upcast
Slice
Downcast
a th a k
Multiple Inheritance
3
2
u
th a là m t c
m c a ngôn ng dùng
bi u di n m i quan h
c bi t gi a các l p.
Các l p
c tr u t ng hóa và t ch c thành
t s
phân c p l p.
th a là m t m c cao h n c a tr u t ng
hóa, cung c p m t c ch gom chung các l p có
liên quan v i nhau thành m t m c khái quát hóa
c tr ng cho toàn b các l p nói trên.
Các l p v i các c
m t ng t nhau có th
c t ch c thành m t s
phân c p k th a.
p trên cùng là tr u t ng hóa c a toàn b
các l p bên d i nó.
9/6/2009
TPT - LTH T
4
1. M
u
Quan h “là 1”:
th a
bi u di n quan h “là 1”.
cs
1. M
ng thông d ng nh t
th a th
t sinh viên là m t ng i
t hình tròn là m t hình ellipse
t tam giác là m t a giác
t cái xe ca “là” xe ng c
t cái xe t i “là” xe ng c
t cái xe máy “là” xe ng c
th a t o kh
ng xây d ng l p m i t
p ã có, trong
ó hàm thành ph n
c th a h ng t
p cha. Trong
C++, k th a còn nh ngh a s
ng thích, nh
ó ta có
ch chuy n ki u t
ng.
th a v a có kh
ng t o c ch khái quát hoá v a có
kh
ng chuyên bi t hoá.
th a cho phép t ch c các l p chia s mã ch ng trình
chung nh
y có th
dàng s a ch a, nâng c p h th ng.
TPT - LTH T
9/6/2009
1. M
5
Th a k cho phép ta nh ngh a 1 l p m i, g i
là l p con (subclass) hay l p d n xu t (derived
class) t
t l p ã có, g i là l p cha
(superclass) hay l p c s (base class).
p d n xu t s th a k các thành ph n (d
li u, hàm) c a l p c s ,
ng th i thêm vào
các thành ph n m i, bao hàm c vi c làm “t t
n” ho c làm l i nh ng công vi c mà trong l p
s ch a làm t t ho c không còn phù h p v i
p d n xu t
9/6/2009
TPT - LTH T
7
ng
c dùng theo hai cách
ph n ánh m i quan h gi a các l p. Là công c
ch c và phân c p l p d a vào s chuyên bi t hóa, trong
ó m t vài hàm thành ph n c a l p con là phiên b n
hoàn thi n ho c
c bi t hoá c a phiên b n
p cha.
Trong C++ m i quan h này th ng
c cài
t s
ng:
th a public.
Hàm thành ph n là ph
ng th c o
ph n ánh s chia s mã ch ng trình gi a các l p
không có quan h
t ng ngh a nh ng có th có t
ch c d li u và mã ch ng trình t ng t nhau. Trong
C++,
ch chia s mã này th ng
c cài t dùng:
th a private.
Hàm thành ph n không là ph
ng th c o.
u
Th a k cho phép nhi u l p
xu t t 1 l p c s
Th a k
ng cho phép m t l
n xu t c a nhi u l p c s
Th a k không ch gi i h n
p d n xu t có th là l p c
p d n xu t khác
9/6/2009
6
TPT - LTH T
9/6/2009
1. M
u
u
TPT - LTH T
có th
n
p có th là
1 m c: M t
s cho các
8
quan h
Thu t ng
p cha – superclass (ho c l p c
it
ng
- base class)
p t ng quát h n trong m t quan h “là”
các i t ng thu c l p cha có cùng t p thu c tính và hành vi S
Tên class
p con – subclass (ho c l p d n xu t – derived class)
p c th
các i t
th a k
con
n trong m t quan h “là”
ng thu c l p con có cùng t p thu c tính và hành vi S (do
p cha), kèm thêm t p thu c tính và hành vi S’ c a riêng l p
(Các) ph
Quan
“là” còn g i là s th a k - Inheritance (ch I trong tam
giác h ng i t ng “P.I.E” (Polymorphism – Inheritance –
Encapsulations))
Ta nói r ng l p con “th a k
” l p cha, ho c l p con
cd n
xu t t ” l p cha
quan h
it
ORD
Thu c tí
tính/P
ng th c public
#
Thu c tí
tính/P
ng th c protected
-
Thu c tí
tính/P
ng th c private
quan h
ng
- name
- address
- studentID
- nextAvailID : int
Private
+publicOp()
# protectedOp()
- privateOp()
it
Student
Class
- privateAttribute
# protectedAttribute
10
TPT - LTH T
9/6/2009
ng
+
ng th c
Object Relationship Diagram
9
TPT - LTH T
9/6/2009
(Các) thu c tính
Tên class
Protected
+ addSchedule(theSchedule : Schedule, forSemester : Semester)
+ getSchedule(forSemester : Semester) : Schedule
+ hasPrerequisites(forCourseOffering : CourseOffering) : boolean
# passed(theCourseOffering : CourseOffering) : boolean
+ getNextAvailID() : int
Public
9/6/2009
TPT - LTH T
11
9/6/2009
TPT - LTH T
12
CHinhVe
quan h
Ví d
ng
Bình th ng: Class bì
bình th ng
In nghiêng:
nghiêng: Class thu n o
G ch d i: Object (không ph i class)
Tên class
(Cá
(Các) thu c tí
tính
(Cá
(Các) ph
it
ng th c
Bình th ng: Thu c tí
tính bì
bình th
In nghiêng:
nghiêng: không s d ng
G ch d i: Thu c tí
tính static
Bình th ng: P
In nghiêng:
nghiêng: P
G ch d i: P
ng
ng th c bì
bình th
ng th c virtual
ng th c static
quan h
i
+ float
+ float
+ void
+ ...
DienTich()
ChuVi()
Ve()
ng
CTuGiac
# CDiem
P1
# CDiem
P2
# CDiem
P3
+ CTamGiac()
+ float
DienTich()
+ float
ChuVi()
+ void
Ve()
+ ...
# CDiem
# CDiem
# CDiem
# CDiem
# CDiem
# float
# float
i
ng
MOTOR VEHICLE
...
CAR
...
Có th bi u di n quan h
i nhi u l p con
theo m t trong hai ki u sau:
MOTOR VEHICLE
...
MOTOR VEHICLE
- passengers
...
TRUCK
- maximum payload
CAR
+ load()
+ unload()
9/6/2009
TPT - LTH T
+ CEllipse()
+ float
DienTich()
+ float
ChuVi()
+ void
Ve()
+ ...
14
Bi u di n m t quan h th a k
gi a hai l p b ng m t m i tên
tr
p con n l p cha
- make
- model
+ drive()
CAR
Tam
A
B
TPT - LTH T
quan h
Ta ã làm quen v i quan h th a k , hãy xem ta có th bi u di n
nó trong s
quan h
i t ng nh th nào
Khi mô t các quan h th a k gi a
các l p trong ORD,
ích là
ch rõ s khác bi t gi a các l p
MOTOR VEHICLE
tham gia quan h ó
- vin
CEllipse
P1
P2
P3
P4
+ CTuGiac()
+ float
DienTich()
+ float
ChuVi()
+ void
Ve()
+ ...
9/6/2009
ng
t l p con khác l p cha a nó ch nào?
các l p con khác nhau ch nào?
MaLoaiHinhVe
CTamGiac
13
TPT - LTH T
9/6/2009
# int
...
15
9/6/2009
TRUCK
...
CAR
...
TPT - LTH T
TRUCK
...
16
quan h
i
ng
quan h
Bi u di n các thu c tính và hành vi
Gi
p MotorVehicle có các thu c
tính vin (s
ng ký xe), make (hãng),
model (ki u), và hành vi drive (lái)
Ta có s
:
p l p con
Gi
, xe ca có thêm thu c tính passengers (s hành khách t
a mà
xe có th ch ); xe t i có thêm thu c tính maximum payload (tr ng t i t i
a) và các hành vi load (b c), unload (d ).
vin
make
model
drive()
Khi bi u di n các thu c tính và hành vi a các l p con, ch
kê các thu c tính/hành vi mà l p cha không có
MOTOR VEHICLE
+
n li t
n gi n hoá s
, không l p l i các thu c tính/hành vi
c th a k
(có th tìm th y chúng b ng cách “l n theo m i tên”)
nh n m nh các
m khác bi t, cho phép d dàng nh n ra lý do cho
vi c l p l p con
i xe t i, xe ca
u có các thu c
tính vin, make,
model, và hành vi
drive
vin
make
model
drive()
CAR
ng
Bi u di n s khác bi t gi a các l p nh th nào?
u không có gì khác nhau thì ch ng có lý do gì
MOTOR VEHICLE
+
i
TRUCK
...
...
17
TPT - LTH T
9/6/2009
18
TPT - LTH T
9/6/2009
MOTOR VEHICLE
quan h
i
...
Cây th a k
ng
CAR
...
Ta có s
:
PICKUP TRUCK
i xe ca u có các thu c
tính vin, make, model, và
hành vi drive,
kèm theo thu c tính
passengers
MOTOR VEHICLE
+
CAR
- passengers
vin
make
model
drive()
TRUCK
- maximum payload
+ load()
+ unload()
9/6/2009
TRUCK
...
TPT - LTH T
i xe t
u có các thu c
tính vin, make, model, và
hành vi drive,
kèm theo thu c tính
maximum payload và các
hành vi load, unload
19
DUMP TRUCK
...
Các quan h th a k luôn
c bi u di n ...
i các l p con t d i l p cha
nh n m nh b n ch t ph
a quan h
Ta ng có th có nhi u t ng th a k , i m i t ng, các l p con ti p
c th a k
p cha
t xe ch rác (dump truck) là xe t i, và c ng là xe ch y b ng
Ngh a là các l p con
c th a k các thu c tính và hành vi
il pc
bên trên nó
ng c
a
t xe ch rác có m i thu c tính và hành vi a xe ng c , kèm theo
i thu c tính và hành vi a xe t i, kèm theo các thu c tính và hành vi
a riêng xe rác.
9/6/2009
TPT - LTH T
20
Ví d MotorVehicle
Nh
i ví d
Ví d MotorVehicle
cây th a k
u b ng
MotorVehicle
nh ngh a l p c
,
NH NGH A
L P C S
MOTOR VEHICLE
+
vin
make
model
drive()
CAR
- passengers
class MotorVehicle {
public:
MotorVehicle(int vin, string make, string model);
~MotorVehicle();
void drive(int speed, int distance);
private:
int vin;
string make;
string model;
};
TRUCK
- maximum payload
MOTOR VEHICLE
*
+
vin
make
model
drive()
+ load()
+ unload()
9/6/2009
21
TPT - LTH T
Ví d MotorVehicle
NH NGH A
L P C S
Ti p theo, nh ngh a constructor, destructor,
và hàm drive()
ây, ta ch nh ngh a t m drive())
9/6/2009
22
TPT - LTH T
Ví d MotorVehicle
NH NGH A
L P CON
Mô t
t l p con ng gi ng nh bi u di n nó trong
ORD, ta ch p trung vào nh ng
m khác v i l p cha
Ích l i
n gi n hoá khai báo l p,
tr nguyên lý óng gói c a h ng i t ng
tr tái s
ng code (s
ng l
nh ngh a c a các thành
viên d li u và ph ng th c)
vi c che d u thông tin ng có th có vai trò trong vi c t o cây
th a k
MotorVehicle::MotorVehicle(int vin, string make, string model)
{
this->vin = vin;
this->make = make;
this->model = model;
}
MotorVehicle::~MotorVehicle() {} // We could actually use
// the default destructor
void MotorVehicle::drive(int speed, int distance)
{
cout << “Dummy drive() of MotorVehicle.” << endl;
}
9/6/2009
TPT - LTH T
23
9/6/2009
TPT - LTH T
24
NH NGH A
L P CON
Ví d MotorVehicle
u, ta t o l p con Car
Ch rõ quan h gi a l p con Car
và l p cha MotorVehicle
class Car : public MotorVehicle
{
public:
Car (int passengers);
~Car();
private:
int passengers;
};
Ví d MotorVehicle
NH NGH A
L P CON
Hi n gi constructor a l p Car ch nh n 1 tham s
passengers, trong khi các i t ng Car ng có t t c
các thành viên
c th a k
MotorVehicle
Car (int passengers);
nói r ng l p m i là l p d n xu t c a m t l p khác, i dòng khai báo, ta
dùng 1 u hai ch m, ti p theo là t khoá truy nh p và tên c a l p cha
Do y, tr khi ta mu n dùng giá tr
nh cho các
thành viên
c th a k , ta nên truy n thêm tham s
cho constructor
kh i t o vin, make, model.
class MyDerivedClass : <keyword> MyBaseClass {...};
9/6/2009
25
TPT - LTH T
Ví d MotorVehicle
NH NGH A
L P CON
sung các tham s cho constructor, ta có khai báo:
26
TPT - LTH T
9/6/2009
Ví d MotorVehicle
NH NGH A
L P CON
Ti p theo, nh ngh a l p m i
i thi u, ta s
nh ngh a constructor và (có th
destructor
Quy
c: t các tham s
cho l p cha lên u danh sách.
class Car : public MotorVehicle
{
public:
Car (int vin, string make, string model, int passengers);
~Car();
private:
int passengers;
};
)
Các l p con không th a k constructor và destructor a l p
cha, do vi c kh i t o và hu các l p khác nhau là khác nhau
Phiên b n constructor
u tiên mà ta có th ngh
i:
Car::Car(int vin, string make, string model, int passengers)
{
this->vin = vin;
this->make = make;
this->model = model;
this->passengers = passengers;
}
Car::~Car() {}
9/6/2009
TPT - LTH T
27
9/6/2009
TPT - LTH T
28
NH NGH A
L P CON
Ví d MotorVehicle
Nh
Ví d MotorVehicle
m
ng constructor a l p c
, ta dùng danh sách kh i t o
a constructor (t ng t nh khi kh i t o các h ng thành viên)
tr c ti p truy nh p các thành viên d li u c a l p c
thi u tính óng gói : ph i bi t sâu v chi ti t l p c
sâu
không tái s
ng mã kh i t o c a l p c
không th kh i t o các thành viên private a l p c
quy n truy nh p
y, ta s
ng constructor
al pc
cách duy nh
và ph i can thi p
Ta
o ph n thu c v th hi n c a l p cha
it
TPT - LTH T
Ví d MotorVehicle
Car::Car(int vin, string make, string model, int passengers)
: MotorVehicle(vin, make, model)
{
this->passengers = passengers;
}
c, sau ó "g n" thêm các
.
29
NH NGH A
L P CON
m b o r ng m t th hi n c a l p c
luôn
c
o tr c, u ta b qua i g i constructor p c
i
danh sách kh i t o c a l p d n xu t, trình biên d ch s
ng chèn thêm l i g i constructor
nh c a l p
Tuy ta c n g i constructor a l p c
t cách
ng minh, i destructor a l p d n xu t, i g i
ng t cho destructor a l p c
là không c n thi t
vi c này
9/6/2009
c th c hi n t
ng
TPT - LTH T
c nh t
ng
i constructor a
MotorVehicle i các tham s
vin, make, model
Ta không c n kh i t o các thành
viên vin, make, model
bên
trong constructor a Car
a
9/6/2009
o tr
nh ngh a constructor nh sau:
do không có
Nguyên t c:
i t ng thu c l p con bao g m m
p cha ng thêm các tính n ng b sung a l p con
t th hi n c a l p c
c t o tr
tính n ng b sung a l p d n xu t
NH NGH A
L P CON
31
9/6/2009
TPT - LTH T
Ví d MotorVehicle
30
NH NGH A
L P CON
Khi t o th hi n c a m t l p
n xu t, các constructor
cg ib
ut
pc
nh t và chuy n d n v phía
p d n xu t
Khi hu th hi n c a l p d n
xu t, các destructor
c g i
u t
p d n xu t, lên
n qua các l p c
(th
ng c l i)
9/6/2009
TPT - LTH T
32
Ví d MotorVehicle
ng t , khai báo và
NH NGH A
L P CON
nh ngh a c a l p Truck nh sau:
class Truck : public MotorVehicle {
public:
Truck (int vin, string make,
string model, int maxPayload);
~Truck();
void Load();
void Unload();
Truck::Truck(int vin, string make,
private:
string model, int maxPayload)
int maxPayload;
:MotorVehicle(vin, make, model)
};
{
this->maxPayload = maxPayload;
}
Quy n truy nh p
(Access privilege)
Ta ã s
ng hai ki u quy n truy nh p cho các thành viên d li u
và ph ng th c
public - thành viên/ph ng th c
có th
c truy nh p t
i t ng C++ thu c ph m vi
private - thành viên/ph ng th c
ch có th
c truy nh p t
bên trong chính l
ó
class Car : public MotorVehicle
{
public:
Car (...);
~Car();
private:
int passengers;
};
Còn có ki u quy n truy nh p th ba: protected
Truck::~Truck() {}
void Truck::Load() {…}
void Truck::Unload() {…}
33
TPT - LTH T
9/6/2009
Quy n truy nh p
Quay i cây th a k
là l p c
i MotorVehicle
class MotorVehicle {
...
private:
int vin;
string make;
string model;
};
i thành viên d li
c
khai báo private, do ó chúng ch có th
c truy nh p t các th hi n c a MotorVehicle
t c các l p d n xu t không có quy n truy nh p các thành viên
private a MotorVehicle
y,
n mã sau s có l i
p Truck không có quy n truy
nh p thành viên private make
al pc
MotorVehicle
9/6/2009
Quy n truy nh p
Tuy quy nh quy n truy nh p nh trên có v
nh ng nó m b o tính óng gói
u không, ta có th
trong c a m t l p ch
c,
c quy n truy nh p vào c u trúc bên
ng cách t o m t l p d n xu t c a l
ó
Tr ng h p n u ta xây d ng l p c
và c ý mu n
“c p” cho l p d n xu t quy n truy nh p t i m t s thành
viên/ph ng th c,
khoá protected quy nh quy n truy nh p cho các thành
viên/ph ng th c s
cs
ng b i l p d n xu t
void Truck::Load() {
if (this->make == “Ford”) {
...
}
}
TPT - LTH T
34
TPT - LTH T
9/6/2009
35
9/6/2009
TPT - LTH T
36
Quy n truy nh p
Quy n truy nh p
khoá protected dùng
p quy n truy nh p t i
thành viên/ph ng th c c a m t l p cho các l p d n
xu t (và ch các l p d n xu t) a l
ó
iv im
i t ng khác c a C++, các thành
viên/ph ng th c protected
c coi nh private
(chúng u không th truy nh
c)
Tuy tiêu chí óng gói khuyên nên
i th private,
nh ng khi t o các cây th a k , ng i ta th ng hay p
quy n truy nh p protected
Gi
ta mu n các l p con a MotorVehicle có th truy nh p d
li u c a nó
Thay t khoá private ng protected, class MotorVehicle {
...
ta có khai báo:
protected:
int vin;
string make;
string model;
};
y,
n mã sau s không có l i
Tuy nhiên truy nh p t bên ngoài
ns
m
p Truck ã có quy n truy nh p
thành viên protected make
al pc
MotorVehicle
9/6/2009
37
TPT - LTH T
Quy n truy nh p
9/6/2009
void Truck::Load() {
if (this->make == “Ford”) {
...
}
}
38
TPT - LTH T
Quy n truy nh p
Các quy n truy nh p có vai trò gì trong
quan h th a k ?
Các quy n truy nh p có vai trò gì trong quan h
th a k ?
Bây gi , ta chuy n sang cách s
ng các
khoá quy n truy nh p trong khai báo
ch ki u th a k
Bây gi , ta chuy n sang cách s
ng các t
khoá quy n truy nh p trong khai báo l
ch
ki u th a k
class Car : public MotorVehicle
{
...
class Car : public MotorVehicle
};
{
class Car : protected MotorVehicle
class Car : private MotorVehicle
9/6/2009
TPT - LTH T
39
9/6/2009
TPT - LTH T
...
{
{
};
...
...
};
};
40
Ki u th a k
khoá
ng
nó quy
c dùng
Ki u th a k
ch rõ “ki u” th a k
class Car : public MotorVehicle
cs
nh nh ng ai có th "nhìn th y" quan h th a k
ó
Nh c l i: p Car th a k
p MotorVehicle có ngh a các
i t ng Car ng có các thành viên d li u và ph ng
th c c a MotorVehicle.
“nhìn th y” quan h th a k gi a Car và MotorVehicle ngh a là
có th truy nh p t i các thành viên mà Car
c th a k
MotorVehicle.
có th truy nh p m i thành viên/ph
ng th c public
a l p cha
c th a k gi nguyên quy n truy
42
TPT - LTH T
9/6/2009
a
Ki u th a k
class Car : private MotorVehicle
Th a k private: ch có chính th hi
th a k
p cha
{
...
};
class Car : protected MotorVehicle
ó bi t nó
c
i t ng bên ngoài không th truy nh p các thành viên
c th a k
Nói cách khác,
i thành viên
thành private trong l p con
c th a k
u tr
Có th dùng th a k private
o l p con có m i
ch c n ng/d ch v
a l p cha nh ng l i không cho bên
ngoài bi t v các ch c n ng ó.
9/6/2009
};
các thành viên public a cha ng
c coi nh public a con
các thành viên protected a cha ng
c coi nh protected
con
Ki u th a k
các
...
Th a k public (lo i thông d ng nh t): quan h th a k
c nhìn
th y t
in i
i t ng C++ khi t ng tác v i m t th hi n c a l p con u
có th coi nó nh
t th hi n c a l p cha
nói cách khác, các thành viên
nh p
41
TPT - LTH T
9/6/2009
{
TPT - LTH T
43
{
...
};
Khi dùng ki u th a k protected, ngoài l
c th a
, ch có các l p con a l
ó nhìn th y quan h
th a k
quan h “Car th a k MotorVehicle” s
c nhìn th y
bên trong Car
các l p con a Car
nói cách khác, các thành viên
c th a k
truy nh p b
xu ng protected.
9/6/2009
TPT - LTH T
có quy n
44
T NG H P
Ki u th a k
1.
K th a public
Các thành ph n public và protected a l p c s
là các thành ph n public và protected a l p d n
xu t.
2.
3.
private
protected
public
Không th truy c p
s
K th a private
Các thành ph n public và protected a l p c
là các thành ph n private a l p d n xu t.
Hình th c k th a
private
K th a protected
Các thành ph n public và protected a l p c
là các thành ph n protected a l p d n xu t.
Thành ph n
trong trong
pc s
s
protected
private
protected
protected
public
private
protected
public
9/6/2009
TPT - LTH T
45
9/6/2009
TPT - LTH T
46
9/6/2009
TPT - LTH T
47
9/6/2009
TPT - LTH T
48
Cái gì là cái gì?
Cái gì là cái gì?
Khi làm quen v i th a k , ta th ng nh
n
khái ni m r ng m t th hi n c a l p d n xu t có
th
i x nh th nó là m t th hi n c a
pc
ví d , ta có th coi m t th hi n c a Car nh là m t
th hi n c a MotorVehicle
9/6/2009
ng Car u là MotorVehicle
ng Truck u là MotorVehicle
c l i thì không úng (v
ng MotorVehicle
ng MotorVehicle
TRUCK
- maximum payload
+ load()
+ unload()
ng quát)
u là Car
u là Truck
TPT - LTH T
9/6/2009
50
Cái gì là cái gì?
ng ó th hi n r t rõ ràng trong cách ta
ngh a m t l p con
Nh
y,
t th hi n c a Car có quy n truy nh p các thu c tính
và hành vi sau:
nh
t l p con trên cây th a k có m i thu c tính và hành vi
p cha,
ng thêm các thu c tính và hành vi a riêng l p con ó
thành viên d li u: vin, make, model, passengers
ph ng th c: drive()
a
Ng c l i, không có lý gì m t th hi n c a l p cha i có quy n truy
nh p t i thu c tính/hành vi ch
nh ngh a trong l p con
t th hi n c a m t l p con
MotorVehicle không th truy nh p passengers
ng t , các l p anh-ch -em không th truy nh p các thu c
tính/hành vi a nhau
i thu c tính và hành vi (không ph i private) a l p cha,
và các thành viên
nh ngh a riêng cho l p con ó.
it
ng nh
C++
9/6/2009
vin
make
model
drive()
Ví d , trong m t s tr ng h p, ta có th ch o các xe ch y b ng
máy là xe ca. Nh ng trong cây th a k
a ta, không có gì òi h i
ng m i xe ch y b ng máy u là xe ca
Cái gì là cái gì?
Theo ngôn ng
a C++:
có th truy nh p t i:
it
it
it
it
49
TPT - LTH T
+
Ta ã nói r ng t
ng c a th a k là
khai báo các l p con có m i
CAR
thu c tính và hành vi a l p cha. - passengers
Ngh a là, các tuyên b sau là úng
Nh ng các tuyên b ng
Nh
y chính xác ngh a là gì? Trong C++, ta
làm vi
ó nh th nào?
MOTOR VEHICLE
TPT - LTH T
51
9/6/2009
ng Car không th có ph ng th c Load() và UnLoad(),
i t ng Truck không th có passengers
m b o các yêu c
ó nh th nào?
TPT - LTH T
52
Các
i
ng
c th a k trong C++
Trong cây th a k MotorVehicle, gi
c khai báo protected, và ta s
public
pc
ng
c th a k trong C++
Ta có th khai báo các th hi n c a các l
ng chúng nh th nào?
Thí d , khai báo các con tr
i3
ó và s
p:
Các
i
mvPointer->Drive();
cPointer->Drive();
tPointer->Drive();
khai báo các
TPT - LTH T
ng
54
c th a k trong C++
Thí d :
it
ng thu c các l p
// Method defined by this class
// Method defined by base class
// Method defined by base class
Tuy nhiên, các ph ng th
nh ngh a t i m t l p d n xu t ch có
th
c truy nh p b i l
ó
xét ph ng th c Load() a l p Truck
...
mvPointer = new MotorVehicle(10, “Honda”, “S2000”);
cPointer = new Car(10, “Honda”, “S2000”, 2);
tPointer = new Truck(10, “Toyota”, “Tacoma”, 5000);
...
9/6/2009
TPT - LTH T
9/6/2009
Trong c ba tr ng h p, ta có th truy nh p các ph ng
th c c a l p cha, do ta ã s
ng ki u th a k public
MotorVehicle* mvPointer;
Car* cPointer;
Truck* tPointer;
ng các con tr
ng ng
c th a k trong C++
class Truck : public MotorVehicle {
public:
Truck(int vin, string make, string model, int maxPayload);
~Truck();
void Load();
void Unload();
protected:
int maxPayload;
};
53
TPT - LTH T
i
ng
class Car : public MotorVehicle {
public:
Car(int vin, string make, string model, int passengers);
~Car();
protected:
int passengers;
};
class MotorVehicle {
public:
MotorVehicle(int vin, string make, string model);
~MotorVehicle();
void Drive(int speed, int distance);
protected:
int vin;
string make;
string model;
};
Các
i
Các l p d n xu t Car và Truck:
i thành viên d li u
ng ki u th a k
MotorVehicle:
9/6/2009
Các
mvPointer->Load();
cPointer->Load();
tPointer->Load();
55
9/6/2009
// Error
// Error
// Method defined by this class
TPT - LTH T
56
Upcast
Upcast
Các th hi n c a l p con th a k public có th
nó là th hi n c a l p cha.
ph
i x nh th
th hi n c a l p con, ta có quy n truy nh p các thành viên và
ng th c public mà ta có th truy nh p t
t th hi n c a l p cha.
áng l u ý là ta th c hi n t t c các l nh gán ó
mà không c n i ki u t ng minh
do
i l p con a MotorVehicle u ch c ch n có m i thành
viên và ph ng th c có trong m t MotorVehicle, vi c t ng tác
i th hi n c a các l p này nh th chúng là MotorVehicle
không có chút r i ro nào
Ví d , nh sau ây là h p l , t k mvPointer2 ang tr
im t
MotorVehicle,
t Car, hay
t Truck
Do ó, C++ cho phép dùng con tr
c khai báo thu c lo i con tr
il pc
ch i th hi n c a l p d n xu t
ta có th th c hi n các l nh sau:
MotorVehicle* mvPointer2;
mvPointer2->Drive();
mvPointer2 = mvPointer;
// Point to another MotorVehicle
mvPointer2 = cPointer;
mvPointer2 = tPointer;
// Point to a Car
// Point to a Truck
TPT - LTH T
9/6/2009
57
Upcast
upcast
Upcast th ng g p t i các nh ngh a hàm, khi m t con
tr /tham chi
nl pc
c yêu c u, nh ng con
tr /tham chi
n l p d n xu t c ng
c ch p nh n
xét hàm sau
i v i con tr
MotorVehicle* mvPointer2 = cPointer;
ví d
upcast
58
Upcast
Upcast là quá trình t ng tác v i th hi n c a l p d n xu t nh th
nó là th hi n c a l p c
.
th , ây là vi
i m t con tr (ho c tham chi u) i l p d n
xu t thành m t m t con tr (ho c tham chi u) i l p c
ta ã th y ví d
TPT - LTH T
9/6/2009
void sellMyVehicle(MotorVehicle& myVehicle) {...}
i v i tham chi u
có th
i sellMyVehicle
t cách h p l
i tham s là m t
tham chi u t i m t MotorVehicle,
t Car, ho c m t Truck.
// Refer to the instance pointed to by cPointer
MotorVehicle& mvReference = *cPointer;
// Refer to an automatically-allocated instance c
Car c(10, “Honda”, “S2000”, 2);
MotorVehicle& mvReference2 = c;
9/6/2009
TPT - LTH T
59
9/6/2009
TPT - LTH T
60
Upcast
Upcast
u ta dùng m t con tr
il pc
tr
i m t th
hi n c a l p d n xu t, trình biên d ch s ch cho ta coi
i t ng nh th nó thu c l p c
Nh
Chú ý ng khi g n m t con tr /tham chi u l p c
i m t th
hi n c a l p d n xu t, ta không h thay i b n ch t c
i t ng
c tr
i
Ví d ,
y, ta không th làm nh sau
không làm m t th hi n c a Truck suy gi m thành m t MotorVehicle,
nó ch cho ta m t cách nhìn khác i v
i t ng Truck và t ng tác
i t ng ó.
Do y, ta v n có th truy nh p t i các thành viên và ph ng th c c a
p d n xu t ngay c sau khi gán con tr
pc
i nó:
MotorVehicle* mvPointer2 = tPointer; // Point to a Truck
mvPointer2->Load();
// Error
ó là vì trình biên d ch không th
m b o r ng con tr th c ra
ang tr
i m t th hi n c a Truck.
TPT - LTH T
9/6/2009
61
mvPointer2 = tPointer;
// Point to a Truck
tPointer->Load();
// We can still do this
mvPointer2->Load();
// Even though we can’t do this (error)
62
TPT - LTH T
9/6/2009
Slicing
Slicing
ôi khi ta mu
nh
MotorVehicle* mvPointer2 = tPointer; // Point to a Truck
i h n ki u
Ví d
Ví d , ta mu n t o m t th hi n c a MotorVehicle d a trên m t
th hi n c a Car (s
ng copy constructor cho MotorVehicle)
Car c(10, “Honda”, “S2000”, 2)’
MotorVehicle mv(c);
Slicing là quá trình chuy n m t th hi n c a l p d n xu t
thành m t th hi n c a l p c
p l vì m t th hi n c a l p d n xu t có t t c các thành viên
và ph ng th c c a l p c
a nó
ây,
t th hi n c a MotorVehicle
c t o b i copy
constructor ch gi
i nh ng thành viên c a Car mà có trong
MotorVehicle
(Car instance)
Quy trình này g i là “slicing” vì th c ch t ta c t b t (slice
off) nh ng thành viên d li u và ph ng th
nh
ngh a trong l p d n xu t
(MotorVehicle instance)
c
mv
vin
make
model
passengers
vin
make
model
sliced off
9/6/2009
TPT - LTH T
63
9/6/2009
TPT - LTH T
64
Slicing
Downcast
Th c ra, quy trình này c ng gi ng h t nh khi ta
ng
i gi a các ki u d li u có s n và b
t
t d li u (ch ng h n khi i m t s ch m
ng sang
nguyên)
Slicing còn x y ra khi ta dùng phép gán
Car c(10, “Honda”, “S2000”, 2)’
MotorVehicle mv = c;
65
TPT - LTH T
9/6/2009
Downcast
Upcast là i con tr /tham chi u t i l p
n xu t thành con tr /tham chi u t i l p
.
Downcast là quy trình ng c l i: i ki u
con tr /tham chi u t i l p c
thành con
tr /tham chi u t i l p d n xu t.
downcast là quy trình r c r i h n và có
nhi
m không an toàn
Downcast
Tr c h t, downcast không ph i là m t quy trình t
òi h
i ki u t ng minh (explicit type cast)
ó là h p lý
ng - nó luôn
u ta bi t ch c ch n r ng m t con tr
pc
i m t l p con, ta có th
i ki u cho con tr
cách s
ng static_cast
nh
i r ng: không ph i “m i xe ch y b ng máy u là xe t i”
do ó, c r i s
y sinh n u trình biên d ch cho ta i m t con tr
t
i MotorVehicle thành m t con tr
i Truck, trong khi th c ra
con tr
ang tr
im
i t ng Car.
Ví d ,
n mã sau s gây l i biên d ch:
MotorVehicle* mvPointer3;
…
Car* cPointer2 = mvPointer3;
Truck* tPointer2 = mvPointer3;
MotorCycle mcPointer2 = mvPointer3;
9/6/2009
66
TPT - LTH T
9/6/2009
TPT - LTH T
qu th
pc
ang tr
ng
Car* cPointer = new Car(10, “Honda”, “S2000”, 2);
MotorVehicle* mv = cPointer;
// Upcast
Car* cPointer2;
cPointer2 = static_cast<Car*>(mv); // Explicit downcast
Ta có th th y m i nguy hi m khi làm vi c này - chuy n gì x y ra
i t ng ta ang c
i ki u th c ra không thu c l p mà ta
ngh ?
Truck* tPointer = new Truck(10, “Toyota”, “Tacoma”, 5000);
// Error
// Error
// Error
MotorVehicle* mv = tPointer; // Upcast
Car* cPointer2;
cPointer = static_cast<Car*>(mv); // Explicit downcast
67
9/6/2009
TPT - LTH T
68
a th a k - Multiple Inheritance
Downcast
Truck* tPointer = new Truck(10, “Toyota”, “Tacoma”, 5000);
MotorVehicle* mv = tPointer; // Upcast
Car* cPointer2;
cPointer = static_cast<Car*>(mv); // Explicit downcast
n mã trên hoàn toàn h p l và s
c trình biên
ch ch p nh n
Tuy nhiên, u ch
n trình trên, ch ng trình có th
(th ng là khi l
u truy nh
n thành
viên/ph ng th
nh ngh a c a l p d n xu t mà
ta i t i)
69
TPT - LTH T
9/6/2009
a th a k
STUDENT
* student ID
- name
- GPA
Xét m t h th ng qu n lý
nhân viên
EMPLOYEE
* employee ID
- name
- office number
ng th c Foo()
Do tính ph c t p ti m tàng c
a th a k ,
t s ngôn
ng
p trình (ch ng h n Java, C#) không cài t tính
ng này.
70
TPT - LTH T
9/6/2009
a th a k
STUDENT
* student ID
- name
- GPA
EMPLOYEE
* employee ID
- name
- office number
STUDENT-EMPLOYEE
- tuition credit
i h c l u tr thông tin
sinh viên và
Ta có th th y các trùng l p ti m tàng trong các thành
viên d li u, ch ng h n l p Student-Employee th a k
thành viên name
hai l p c
trong C++, có th gi i quy t r c r i do trùng tên này b ng toán t
ph m vi (cho trình biên d ch bi t ta ang nói n name nào)
i cùng lúc v a là sinh viên v a là nhân viên
TPT - LTH T
hai l p cùng có ph
- tuition credit
có th sinh viên-nhân viên có thêm thu c tính n
9/6/2009
ch ng h n n u th a k
STUDENT-EMPLOYEE
sinh viên có th có các thu c tính ch ng h n tên, mã sinh viên, và
m
trung bình
nhân viên có th có các thu c tính tên, mã nhân viên, phòng làm vi c
Có th có nh ng ng
a th a k là d ng th a k ph c t p cho phép ta t o
các l p d n xu t th a k các thu c tính và hành vi
nhi u h n m t l p c
.
Nên h n ch
ng a th a k vì nó có th
n
lo i nh m l n do các tên trùng nhau
c phí (tuition credit)
71
9/6/2009
TPT - LTH T
72
a th a k - cài
a th a k
Ví d
a th a k
trong cây th a k
Nguyên lý th a k
n
không i: p con th a
i thu c tính và
hành vi a l p cha
PERSON
- name
- address
- phone number
STUDENT
* student ID
- GPA
Trong C++,
ó có
ngh a l p d n xu t th a
i thành viên d li u
và ph ng th c c a t ng
pc
9/6/2009
TPT - LTH T
t
Khai báo m t l p là d n xu t c a nhi u l p c
:
class StudentEmployee : public Student, public Employee {
...
};
nh ngh a l p d n xu t, constructor
:
StudentEmployee::StudentEmployee
EMPLOYEE
i constructor
a các l p
(...)
: Student(...), Employee(...) {
...
};
* employee ID
- office number
Khi g p mù m
tên (ch ng h n 2 phiên b n name th a k
2
pc
trong ví d tr c) ta có th
ng toán t ph m vi
STUDENT-EMPLOYEE
this->Student::name // Refers to the version of name
// inherited from Student
this->Employee::name // Refers to this version of name
// inherited from Employee
- tuition credit
73
9/6/2009
TPT - LTH T
74
9/6/2009
TPT - LTH T
76
a th a k
Trong th c t , có m t lo t các v
ti m tàng
liên quan
a th a k , ph n l n là do c r i
vì mù m
Có th ta không bao gi
n dùng
a th a
, nh ng c ng có nh ng tình hu ng mà a
th a k là l i gi i t t nh t (và có th là duy nh t)
us
ng a th a k , nh t thi t ph i cân
nh c v các xung t có th
y sinh trong khi
ng các l p có liên quan.
9/6/2009
TPT - LTH T
75