Tải bản đầy đủ (.pdf) (25 trang)

Chương 4 Kế thừa C++

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (475.58 KB, 25 trang )

Chương 4: Kế thừa
Phần 2: Ngôn ngữ lập trình C++
Các nội dung chính
 Các khái niệm cơ bản
 Phân loại kế thừa
 Kế thừa đơn
 Tính đa hình
 Lớp trừu tượng
 Kế thừa bội
Các khái niệm cơ bản
 Kế thừa (inheritance):
Lớp B kế thừa lớp A, tức là B sẽ có thể tái sử
dụng các thành phần dữ liệu và các thao tác
trong A
A
B
Lớp cha (lớp cơ sở)
Lớp con (lớp dẫn xuất)
Ví dụ về sự kế thừa
Lớp Số
+, -, *, /
<,>,==,…

Giá trị
Lớp Số Thực
+, -, *, /
<,>,==,…

Giá trị thực
Lớp Số Nguyên
+, -, *, /


<,>,==,…

Giá trị nguyên
Lớp Phân Số
+, -, *, /
<,>,==,…

Giá trị mẫu số
Lớp Số Phức
+, -, *, /
<,>,==,…

Giá trị phức
Phân loại kế thừa
 Có hai cách phân loại
 Theo mức độ kế thừa: có 2 mức
 Public: bảo toàn mức độ che dấu của các thành phần của
lớp cơ sở trong lớp dẫn xuất
 Private: đưa các mức che dấu của các thành phần trong lớp
cơ sở lên mức private trong lớp dẫn xuất
 Theo số lượng lớp cơ sở: có 2 loại
 Kế thừa đơn
 Kế thừa bội
Cú pháp khai báo kế thừa
 Kế thừa đơn
 Trong đó E có thể
là:
 public
 private


 Kế thừa bội
class B: <E> A {
//Đ/n phần thân của lớp dẫn xuất
};
class C: <E
A
> A, <E
B
> B {
//Đ/n phần thân của lớp dẫn xuất
};
Kế thừa đơn
 Chương trình 4.1: xây dựng hai lớp số Real và
Complex, trong đó lớp Complex kế thừa lớp
Real

class Real {
protected:
float r;
public:
Real(float a=0){
r = a;
}
//tiếp ở hình bên
};
class Real {
//tiếp từ hình bên
Real Add(Real x){
Real z;
z.r = x.r +r;

return z;
}
void Print(){
cout<<r;
}
};
Chương trình 4.1 (tiếp)
class Complex: public
Real {
float i; //Phan ao
public:
Complex(float rp=0, float
ip=0):Real(rp){
i=ip;
}
//tiếp ở hình bên

};
class Complex: public
Real {
//tiếp từ hình bên
Complex Add(Complex
x){
Complex a;
a.r = x.r +r;
a.i = x.i +i;
return a;
}
void Print(){
Real::Print();

cout<<"+j"<<i;
}
};
Chương trình 4.1 (tiếp và hết)
main(){
Real x, y(10.5),z(25.5);
x = y.Add(z);
cout<<"x="; x.Print();
cout<<endl;

Complex c, d(5,6), e(6,9);
c = d.Add(e);
cout<<"c="; c.Print();
cout<<endl;

return
system("PAUSE"),EXIT_SUCCESS;
}
Kết quả chạy
Tính đa hình và hàm ảo
 Khái niệm đa hình:
 Ta thấy trong chương trình ở trên, trong hàm main
có các đối tượng của cả lớp Real và Complex. Các
đối tượng này đều có hàm thành viên Print() không
có tham số để in ra nội dung của từng đối tượng. Do
đó, khi hàm main gửi thông báo Print cho các đối
tượng, yêu cầu hiển thị nội dung của chúng thì các
đối tượng đều gọi hàm Print để in nội dung của
chúng ra màn hình. Do các đối tượng có các nội
dung khác nhau nên các nội dung in ra cũng khác

nhau. Đây được gọi là sự đa hình, và hàm thành viên
giống nhau cho nhiều lớp khác nhau được gọi là hàm
đa hình.
Tính đa hình
main()
:a Real
Print()
:a Complex
Print()
Print
Print
Vấn đề với tính đa hình
main(){
Real x(10.5);
cout<<"x="; x.Print(); cout<<endl;

Complex c(6,9);
cout<<"c="; c.Print(); cout<<endl;
Real *pr = &x;
cout<<"x=";pr->Print();cout<<endl;
pr=&c;
cout<<"c=";pr->Print();cout<<endl; //Vấn đề ở đây
return system("PAUSE"),EXIT_SUCCESS;
}
Kết quả chạy
Vấn đề với tính đa hình
 Vấn đề nằm ở dòng in ra c = 6, tức là chỉ in ra
phần thực của c, mặc dù con trỏ pr đã trỏ vào c
 Nguyên nhân:
 Do bên trong mỗi đối tượng thuộc lớp Complex có 2

hàm Print(), một kế thừa từ lớp Real, và một được
định nghĩa lại trong lớp Complex, nên khi gọi pr-
>Print(), hệ thống đã liên kết và gọi đến hàm Print
của lớp Real, vì nó chỉ xét kiểu của con trỏ pr là kiểu
Real, chứ không xét đến bản thân kiểu của đối tượng
mà pr đang trỏ đến. Đây là hình thức liên kết sớm
(early binding), được thực hiện vào lúc dịch chương
trình
Giải pháp cho vấn đề đa hình
 Sử dụng hàm ảo
(virtual)
 Thêm từ khóa virtual
vào khai báo của hàm
Print trong lớp Real
 Khi đó hàm Print trong
lớp Complex cũng là
hàm virtual, mặc dù ta
không cần lặp lại từ
khóa này trong đ/n của
hàm này
class Real {
//tiếp từ hình bên
Real Add(Real x){
Real z;
z.r = x.r +r;
return z;
}
virtual void Print(){
cout<<r;
}

};
Kết quả chạy lại
Hàm ảo và cơ chế liên kết muộn
 Cơ chế liên kết muộn (late binding)
 Khi gặp hàm ảo, thì hệ thống không thực hiện liên
kết sớm khi dịch chương trình, mà chờ đến khi chạy
chương trình, sau khi xác định rõ kiểu của đối tượng
mà thi hành hàm đó, thì việc liên kết mới được thực
hiện, nhằm tìm đúng loại hàm cần thiết để thực hiện.
Lớp trừu tượng và hàm ảo thuần túy
 Hàm ảo thuần túy (pure virtual function):
 Là hàm ảo không có phần định nghĩa (không
có phần thân hàm)
 Lớp trừu tượng (abstract class):
 Là lớp có ít nhất một hàm thành viên là ảo
thuần túy
Ví dụ
//Đ/n lớp trừu tượng
class Number {
//Khai báo hàm ảo thuần túy
public:
virtual void Print()=0;
};
class Integer: public Number {
public:
void Print();
};
class Real: public Number {
public:
void Print();

};
class Integer
Print()
class Real
Print()
Abs class Number
virtual Print()=0
Lớp trừu tượng
 Một số quy tắc:
 Lớp trừu tượng không có đối tượng, nó được dùng
để khái quát các thành phần chung nhất của các lớp
 Có thể khai báo con trỏ kiểu lớp trừu tượng
 Một hàm ảo thuần túy trong lớp trừu tượng cần phải
được định nghĩa lại trong lớp dẫn xuất; hoặc tiếp tục
là hàm ảo trong lớp đó, khi đó lớp dẫn xuất này lại là
trừu tượng.
Kế thừa bội
 Bài tập về nhà nghiên cứu
Tóm tắt
 Khái niệm cơ bản về kế thừa
 Cách phân loại kế thừa
 Tính đa hình và cách cài đặt
 Sự khác nhau giữa hàm ảo và hàm thông thường
 Lớp trừu tượng và hàm ảo thuần túy
 Kế thừa bội

Bài tập
 Bài 1: Xây dựng cây các lớp số: gồm các lớp Number, Integer,
Fraction, Real, Complex có nút gốc là lớp Number. Mỗi lớp gồm
các thao tác:

 Số học: +,-,*,/
 So sánh: <,>,==
 Phép xuất ra màn hình <<
 Bài 2: Xây dựng một cây các lớp hình: gồm các lớp Shape,
Rectangle, Square, Triangle, Quadrangle. Mỗi lớp gồm các thao
tác:
 Hàm tạo, tạo ra một hình có tên cho trước
 Tính diện tích
 Tính chu vi
 In ra màn hình nội dung của hình, gồm tên, loại hình, chu vi
và diện tích của nó
Thank you!

Tài liệu bạn tìm kiếm đã sẵn sàng tải về

Tải bản đầy đủ ngay
×