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

Bài giảng Ngôn ngữ lập trình C và C++: Bài 7 - TS. Đỗ Đăng Khoa

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 (154.83 KB, 23 trang )

5/18/2015

TRƯỜNG ĐẠI HỌC BÁCH KHOA HÀ NỘI

Ngơn ngữ lập trình C và C++
Bài 7: Kế thừa và Đa xạ

TS. Đỗ Đăng Khoa
Bộ mơn Cơ học Ứng dụng
Viện Cơ khí
/>
1


5/18/2015

Khái niệm về Kế thừa
Kế thừa cho phép định nghĩa một lớp mới từ một lớp khác
nhằm mở rộng và sử dụng lại các thành phần dữ liệu và hàm của
lớp cũ thay vì phải viết mới hồn tồn
Một lớp được kế thừa từ lớp khác được gọi là lớp dẫn xuất,
hoặc lớp con
Lớp cho phép việc kế thừa gọi là lớp cơ sở hoặc lớp cha
Một lớp có thể là lớp cơ sở cho nhiều lớp dẫn xuất
Một lớp có thể kế thừa từ một hoặc nhiều lớp cơ sở
Hàm dựng và hàm hủy không được phép kế thừa cho các lớp
dẫn xuất
Con trỏ của lớp cơ sở có thể chứa được địa chỉ của các đối
tượng của lớp dẫn xuất
TRƯỜNG ĐẠI HỌC
BÁCH KHOA HÀ NỘI



2


5/18/2015

Khái niệm về Kế thừa
Lớp kế thừa mặc nhiên có thể sử dụng một phần hoặc toàn bộ
các thành phần của lớp cơ sở
Tuỳ thuộc vào kiểu kế thừa. Có 3 kiểu kế thừa: public,
protected và private
Ví dụ về kế thừa:

TRƯỜNG ĐẠI HỌC
BÁCH KHOA HÀ NỘI

3


5/18/2015

Khai báo lớp kế thừa đơn
Cú pháp:
class derived-class: access-specifier base-class
Trong đó:
derived-class: Tên lớp mới
access-specifier: Kiểu kế thừa là public, protected hoặc
private
base-class: Tên lớp đã có.
Nếu access-specifier khơng sử dụng, thì mặc định là kế

thừa private.

TRƯỜNG ĐẠI HỌC
BÁCH KHOA HÀ NỘI

4


5/18/2015

Khai báo lớp kế thừa đơn
Ví dụ: Lớp cơ sở Shape, và lớp dẫn xuất Rectangle.
#include <iostream>
using namespace std;
// Base class
class Shape{
public:
void setWidth(int w){
width = w;
}
void setHeight(int h){
height = h;
}
TRƯỜNG ĐẠI HỌC
BÁCH KHOA HÀ NỘI

5


5/18/2015


Khai báo lớp kế thừa đơn
protected:
int width;
int height;
};
// Derived class
class Rectangle: public Shape{
public:
int getArea(){
return (width * height);
}
};

TRƯỜNG ĐẠI HỌC
BÁCH KHOA HÀ NỘI

6


5/18/2015

Khai báo lớp kế thừa đơn
int main(void){
Rectangle Rect;
Rect.setWidth(5);
Rect.setHeight(7);
// Print the area of the object.
cout << "Total area: " << Rect.getArea() <<
endl;

return 0;
}
TRƯỜNG ĐẠI HỌC
BÁCH KHOA HÀ NỘI

7


5/18/2015

Quyền truy cập
Lớp dẫn xuất có thể truy cập tất cả các thành phần không phải
private
Bảng tổng hợp các quyền truy cập

TRƯỜNG ĐẠI HỌC
BÁCH KHOA HÀ NỘI

8


5/18/2015

Kiểu kế thừa
Khi dẫn xuất một lớp từ lớp cơ sở, lớp cơ sở có thể được kế
thừa theo public, protected và private
Kế thừa public: tất cả thành phần public, protected của lớp cơ
sở sẽ là thành phần public, protected tương ứng của lớp dẫn
xuất. Các thành phần private của lớp cơ sở không truy cập trực
tiếp từ lớp dẫn xuất, nhưng có thể truy cập bằng cách gọi các

thành phần public và protected của lớp cơ sở.
Kế thừa protected: Các thành phần public, protected của lớp
cơ sở sẽ là thành phần protected của lớp dẫn xuất.
Kế thừa private: Các thành phần public, protected của lớp cơ
sở sẽ là thành phần private của lớp dẫn xuất
TRƯỜNG ĐẠI HỌC
BÁCH KHOA HÀ NỘI

9


5/18/2015

Đa kế thừa
Một lớp có thể kế thừa các thành phần từ nhiều lớp cơ sở,
được khai báo như sau:
class derived-class: access baseA, access
baseB...
access: là public, protected hoặc private.
Ví dụ:
#include <iostream>
using namespace std;
// Base class Shape
class Shape{
public:
TRƯỜNG ĐẠI HỌC
BÁCH KHOA HÀ NỘI

10



5/18/2015

Đa kế thừa
void setWidth(int w)
{
width = w;
}
void setHeight(int h)
{
height = h;
}
protected:
int width;
int height;
};
TRƯỜNG ĐẠI HỌC
BÁCH KHOA HÀ NỘI

11


5/18/2015

Đa kế thừa
// Base class PaintCost
class PaintCost
{
public:
int getCost(int area)

{
return area * 70;
}
};

TRƯỜNG ĐẠI HỌC
BÁCH KHOA HÀ NỘI

12


5/18/2015

Đa kế thừa
// Derived class
class Rectangle: public Shape, public PaintCost
{
public:
int getArea()
{
return (width * height);
}
};

TRƯỜNG ĐẠI HỌC
BÁCH KHOA HÀ NỘI

13



5/18/2015

Đa kế thừa
int main(void){
int area;
Rectangle Rect;
Rect.setWidth(5);
Rect.setHeight(7);
area = Rect.getArea();
// Print the area of the object.
cout << "Total area: " << Rect.getArea() <<
endl;
// Print the total cost of painting
cout << "Total paint cost: $" <<
Rect.getCost(area) << endl;
return 0; }
TRƯỜNG ĐẠI HỌC
BÁCH KHOA HÀ NỘI

14


5/18/2015

Đa xạ (polymorphism)
Đa xạ thường xảy ra khi có một hệ thống phân cấp các lớp và
chúng có liên quan bởi việc kế thừa.
Đa xạ có nghĩa là việc gọi tới một hàm thành phần sẽ làm cho
làm cho một hàm khác được thực hiện tùy thuộc vào kiểu của đối
tượng đó gọi hàm.


TRƯỜNG ĐẠI HỌC
BÁCH KHOA HÀ NỘI

15


5/18/2015

Đa xạ (polymorphism)
#include <iostream>
using namespace std;
class Shape {
protected:
int width, height;
public:
Shape( int a=0, int b=0)
{
width = a;
height = b;
}
TRƯỜNG ĐẠI HỌC
BÁCH KHOA HÀ NỘI

16


5/18/2015

Đa xạ (polymorphism)

int area(){
cout << "Parent class area :" <return 0;
}
};
class Rectangle: public Shape{
public:
Rectangle( int a=0, int b=0):Shape(a, b) {
}
int area (){
cout << "Rectangle class area :" <return (width * height); }};
TRƯỜNG ĐẠI HỌC
BÁCH KHOA HÀ NỘI

17


5/18/2015

Đa xạ (polymorphism)
class Triangle: public Shape{
public:
Triangle( int a=0, int b=0):Shape(a, b) { }
int area ()
{
cout << "Triangle class area :" <return (width * height / 2);
}
};


TRƯỜNG ĐẠI HỌC
BÁCH KHOA HÀ NỘI

18


5/18/2015

Đa xạ (polymorphism)
// Main function for the program
int main( ){
Shape *shape;
Rectangle rec(10,7);
Triangle tri(10,5);
// store the address of Rectangle
shape = &rec;
// call rectangle area.
shape->area();
// store the address of Triangle
shape = &tri;
// call triangle area.
TRƯỜNG ĐẠI HỌC
BÁCH KHOA HÀ NỘI

19


5/18/2015


Đa xạ (polymorphism)
shape->area();
return 0;}
Kết quả in ra:
Parent class area
Parent class area
Hàm area() được thiết lập một lần bởi trình biên dịch là hàm của
lớp cơ sở. Đây được gọi là liên kết tĩnh – hàm gọi được đã xác
định trước khi chương trình thực hiện
Để giải quyết vấn đề, bổ sung thêm từ khóa virtual trước
hàm area của lớp Shape:
virtual int area()
TRƯỜNG ĐẠI HỌC
BÁCH KHOA HÀ NỘI

20


5/18/2015

Đa xạ (polymorphism)
Kết quả in ra:
Rectangle class area
Triangle class area
Với từ khóa virtual, trình biên dịch tìm kiếm nội dung của con
trỏ thay vì kiểu của nó. Do đó, từ lúc địa chỉ của các lớp Triangle
và Rectangle được chứa trong *shape, hàm area tương ứng sẽ
được gọi.
Chúng ta có các lớp với một hàm tên giống nhau, thậm chí cùng
tham số, nhưng được triển khai khác nhau. Đây là cách đa xạ

thường được dùng

TRƯỜNG ĐẠI HỌC
BÁCH KHOA HÀ NỘI

21


5/18/2015

Hàm ảo (Virtual Function)
Hàm ảo là hàm trong lớp cơ sở được khai báo sử dụng từ khóa
virtual
Việc định nghĩa một hàm ảo trong lớp cơ sở, một hàm tương tự
trong lớp dẫn xuất nhằm nói với trình biên dịch hàm này không
được liên kết tĩnh mà là liên kết động.
Hàm ảo khơng dùng cho hàm dựng nhưng có dùng cho hàm
hủy

TRƯỜNG ĐẠI HỌC
BÁCH KHOA HÀ NỘI

22


5/18/2015

Hàm thuần ảo
Hàm thuần ảo được khai báo như sau:
virtual kiểu tên_hàm() = 0;

Hàm thuần ảo khơng có thân hàm
Khai báo hàm thuần ảo trong lớp cơ sở nhằm yêu cầu các lớp
dẫn xuất từ lớp này bắt buộc phải có phần triển khai riêng hàm
đó.

TRƯỜNG ĐẠI HỌC
BÁCH KHOA HÀ NỘI

23



×