1. Trang chủ
  2. » Giáo án - Bài giảng

Giáo án - Bài giảng: KỸ THUẬT THỪA KẾ TRONG C++

56 842 10
Tài liệu đã được kiểm tra trùng lặp

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Tiêu đề Kỹ Thuật Thừa Kế Trong C++
Trường học Đại học Bách Khoa Hà Nội
Chuyên ngành Lập trình C++
Thể loại Giáo án bài giảng
Năm xuất bản 2023
Thành phố Hà Nội
Định dạng
Số trang 56
Dung lượng 1,77 MB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

Cài đặt sự thừa kếSử dụng các thành phần của lớp cơ sở Định nghĩa lại các hàm thành phần Truyền thông tin giữa các hàm thiết lập của lớp dẫn xuất và lớp cơ sở Các loại dẫn xuất khác

Trang 1

Cài đặt sự thừa kế

Sử dụng các thành phần của lớp cơ sở

Định nghĩa lại các hàm thành phần

Truyền thông tin giữa các hàm thiết lập của lớp dẫn xuất và lớp cơ sở

Các loại dẫn xuất khác nhau và sự thay đổi trạng thái của các thành phần lớp

cơ sở

Sự tương thích giữa các đối tượng của lớp dẫn xuất và lớp cơ sở

Toán từ gán và thừa kế

Hàm ảo và tính đa hình

Hàm ảo thuần tuý và lớp cơ sở trừu tượng

Đa thừa kế và các vấn đề liên quan

Trang 2

1 GIỚI THIỆU

- Thừa kế cho phép ta định nghĩa một lớp mới, gọi là lớp dẫn xuất, từ một lớp đã có, gọi là lớp cơ

sở Lớ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 các thành phần mới

- Thừa kế cho phép không cần phải biên dịch lại các thành phần chương trình vốn đã có trong các lớp cơ sở và hơn thế nữa không cần phải có chương trình nguồn tương ứng

Trang 3

chênh lệch giá mua bán

Lớp: xe gắn máy thừa kế từ lớp mặt hàng nhập khẩu

Trang 5

Lớ p dẫn xuất chỉ thừa kế từ một lớp cơ cở

point(float ox, float oy) {x = ox; y = oy; }

point(point &p) {x = p.x; y = p.y;}

coloredpoint(float ox, float oy, unsigned int c):point(ox,oy) {

color = c;

} coloredpoint(coloredpoint &b):point((point &)b) {

color = b.color; } void display() {

cout<<"Ham coloredpoint::display()\n";

point::display();//

cout<<"Mau "<<color<<endl;

} };

Trang 6

Lớp dẫn xuất chỉ thừa kế từ một lớp cơ cở

Trang 7

- Các thành phần private trong lớp cơ sở không thể truy nhập được từ các lớp dẫn xuất

- Lớp dẫn xuất có thể truy nhập đến thành phần protected và public của lớp cơ sở

- Phạm vi của lớp dẫn xuất che lấp lớp cơ sở, do đó ta cần dùng toán tử phạm vi :: khi truy xuất đến thành phần thuộc lớp cơ sở mà có đã được kế thừa lại trong lớp dẫn xuất

- Một đối tượng của lớp dẫn xuất có thể thay thế một đối tượng của lớp cơ sở -> có việc chuyển kiểu ngầm định từ một đối tượng thuộc lớp dẫn xuất sang một đối tượng thuộc lớp cơ sở

Trang 8

point(float ox, float oy) {x = ox; y = oy; }

point(point &p) {x = p.x; y = p.y;}

} coloredpoint(float ox, float oy, unsigned int c):point(ox,oy) {

color = c;

} coloredpoint(coloredpoint &b):point((point

&)b) { color = b.color;

} void display() { cout<<"Ham coloredpoint::display()\n"; point::display();/*gäi tíi hµm cïng tªn trong líp c¬ së*/

cout<<"Mau "<<color<<endl;

} };

Trang 10

T ương thích giữa con trỏ lớp dẫn xuất và con trỏ lớp cơ sở

point(float ox, float oy) {x = ox; y = oy; }

point(point &p) {x = p.x; y = p.y;}

coloredpoint(float ox, float oy, unsigned int c):point(ox,oy) {

color = c;

} coloredpoint(coloredpoint &b):point((point

&)b) { color = b.color;

} void display() { cout<<"Ham coloredpoint::display()\n"; point::display();

cout<<"Mau "<<color<<endl;

} };

Trang 11

T ương thích giữa con trỏ lớp dẫn xuất và con trỏ lớp cơ sở

Câu lệnh adp->display(); gọi tới hàm point::display();

Trang 12

T ương thích giữa tham chiếu lớp dẫn xuất và tham chiếu lớp cơ sở

point(float ox, float oy) {x = ox; y = oy; }

point(point &p) {x = p.x; y = p.y;}

coloredpoint(float ox, float oy, unsigned int c):point(ox,oy) {

color = c; } coloredpoint(coloredpoint &b):point((point

&)b) { color = b.color;

} void display() { cout<<"Ham coloredpoint::display()\n"; point::display();

cout<<"Mau "<<color<<endl;

} };

Trang 13

T ương thích giữa tham chiếu lớp dẫn xuất và tham chiếu lớp cơ sở

Câu lệnh adp->display(); gọi tới hàm point::display();

Trang 14

Hàm thiết lập trong lớp dẫn xuất

- Một đối tượng trong lớp dẫn xuất có thể coi là một đối tượng thuộc lớp cơ sở, việc gọi hàm thiết lập trong lớp dẫn xuất sẽ kéo theo việc gọi đến một hàm thiết lập trong lớp cơ sở

- Thứ tự thực hiện của hàm thiết lập: hàm thiết lập của lớp cơ sở, hàm thiết lập của lớp dẫn xuất

Trang 15

float getx() {return x;}

float gety() {return y;}

point() {x = 0; y = 0;}

point(float ox, float oy) {x = ox; y = oy; }

point(point &p) {x = p.x; y = p.y;}

} coloredpoint(float ox, float oy, unsigned int c); coloredpoint(coloredpoint

&b):point(b.getx(),b.gety()) { cout<<"Goi ham thiet lap sao chep""

<<" coloredpoint::coloredpoint(coloredpoint

&) \n";

color = b.color;

} void display() { cout<<"Ham coloredpoint::display()\n";

point::display();

cout<<"Mau "<<color<<endl;

} };

Trang 17

Các kiểu dẫn xuất khác nhau

Trang 18

Dẫn xuất public

- Trong dẫn xuất public các thành phần các hàm bạn và các đối tượng của lớp dẫn xuất không thể truy xuất đến thành phần private của lớp cơ sở

- Các thành phần protected trong lớp cơ sở trở thành các thành phần private trong lớp dẫn xuất

- Các thành phần public của lớp cơ sở vẫn là public trong lớp dẫn xuất

Dẫn xuất private

- Các thành phần public trong lớp cơ sở trở thành các thành phần private trong lớp dẫn xuất

- Các thành phần protected trong lớp cơ sở có thể truy nhập được từ các hàm thành phần và các hàm bạn của lớp dẫn xuất

Dẫn xuất protected

- Các thành phần public, protected trong lớp cơ sở trở thành các thành phần protected trong lớp dẫn xuất

Trang 19

Líp c¬ së DÉn xuÊt public DÉn xuÊt

protected DÉn xuÊt

private

FMA NSD TN TTM NSD TN TTM NSD TN TTM NSD TN

Tõ viÕt t¾t DiÔn giải

Trang 20

- Xây dựng sơ đồ lớp theo đặc tả sau:

Một trường đại học có nhiều cá nhân gồm nhân viên, sinh viên Nhân viên gồm nhân viên quản lý và giảng viên giảng dạy Sinh viên chia làm nhiều loại như học viên cao học, sinh viên chính qui, sinh viên cao đẵng, tại chức Trong trường cũng có nhiều phòng ban và các khoa Đối với nhân viên và cán bộ giảng dạy trường cần quản lý thông tin như mã nhân viên, tên, năm sinh, địa chỉ, hệ số lượng, phòng hay khoa làm việc Đối với giảng viên cần quản lý thêm thông tin về học hàm, học vị, môn giảng dạy Đối với nhân viên cần quản lý thông tin về chuyên môn Đối với khoa hay phòng ban thì quản lý tên, tên trưởng khoa/phòng, số sinh viên theo học từng loại nếu là khoa

Đối với học viên và sinh viên cần quản lý mã số, tên, năm sinh, khóa, thuộc khoa nào, địa chỉ Đối với học viên cao học cần quản lý thông tin chuyên ngành học đại học Đối với học viên tại chức cần quản lý cơ quan công tác

Trang 21

3.1 Giới thiệu

- Một tham trỏ tới đối tượng có thể nhận địa chỉ của bất kỳ đối tượng con cháu nào Tuy nhiên, lời gọi tới một phương thức của một đối tượng được trỏ tới luôn được coi như lời gọi đến phương thức tương ứng với kiểu con trỏ, không phải tương ứng với đối tượng đang trỏ đến Trường hợp này gọi là “gán kiểu tĩnh – static typing” hay “gán kiểu sớm – early binding”

- Để gọi phương thức tương ứng với đối tượng được trỏ đến, cần phải xác định kiểu của đối tượng tại thời điểm thực hiện chương trình Trường hợp này ta gọi là “ gán kiểu động – dynamic typing” hay gán kiểu muộn – late binding”

- C++ đưa ra khái niệm hàm ảo (virtural) để giải quyết trương hợp này

Trang 22

void move(float dx, float dy) {

x += dx;

y += dy;

} };

class coloredpoint : public point { unsigned int color;

public:

coloredpoint():point() { cout<<"coloredpoint::coloredpoint()\n"; color =0;

}

Trang 23

coloredpoint(float ox, float oy, unsigned int c);

coloredpoint(coloredpoint &b):point((point &)b) {

coloredpoint::coloredpoint(float ox, float oy,

unsigned c) : point(ox, oy){

cout<<"coloredpoint pc(2,3,5);\n"; coloredpoint pc(2,3,5);

Trang 24

- Từ khoá virtual có thể đặt trước hay sau tên kiểu dữ liệu nhưng phải trước tên hàm để chỉ rằng là một hàm ảo

- Tuỳ thuộc vào kiểu của đối tượng có địa chỉ chứa trong con trỏ lớp dẫn xuất ptr mà lời gọi hàm

ptr->display() sẽ gọi đến phương thức display() của point hay coloredpoint

Trang 25

x += dx;

y += dy;

} virtual void Identifier() { cout<<"Diem khong mau \n";

} };

void point::display() { cout<<"Toa do : "<<x<<" "<<y<<endl; Identifier();

}

Trang 26

class coloredpoint : public point {

unsigned int color;

coloredpoint(float ox, float oy, unsigned int c);

coloredpoint(coloredpoint &b):point((point &)b) {

cout<<"coloredpoint::coloredpoint(float, float, unsigned)\n";

color = c;

}void main() { clrscr();

Trang 27

3.2 Phạm vi của khai báo virtual: một hàm f được khai báo virtual trong lớp A, nó được xem như thể

hiện của sự ghép kiểu động trong lớp A và trong tất cả các lớp dẫn xuất từ A

x = p.x;

y = p.y;

} void display() ; void move(float dx, float dy) {

x += dx;

y += dy;

} virtual void Identifier() { cout<<"Diem khong mau \n";

} };

Trang 28

3.2 Phạm vi của khai báo virtual: một hàm f được khai báo virtual trong lớp A, nó được xem như thể

hiện của sự ghép kiểu động trong lớp A và trong tất cả các lớp dẫn xuất từ A

void point::display() {

cout<<"Toa do : "<<x<<" "<<y<<endl;

Identifier();

}

class coloredpoint : public point {

unsigned int color;

coloredpoint(float ox, float oy, unsigned int c);

coloredpoint(coloredpoint &b):point((point &)b) {

} };

Trang 29

3.2 Phạm vi của khai báo virtual: một hàm f được khai báo virtual trong lớp A, nó được xem như thể

hiện của sự ghép kiểu động trong lớp A và trong tất cả các lớp dẫn xuất từ A

class threedimpoint : public point {

coloredthreedimpoint(float ox, float oy, float oz,unsigned c):

threedimpoint (ox, oy, oz) {

color = c; } coloredthreedimpoint(coloredthreedimpoint &p) :threedimpoint(p) {

color = p.color;

} void Identifier() { cout<<"Diem mau : "<<color<<endl;

} };

Trang 30

3.2 Phạm vi của khai báo virtual: một hàm f được khai báo virtual trong lớp A, nó được xem như thể

hiện của sự ghép kiểu động trong lớp A và trong tất cả các lớp dẫn xuất từ A

coloredpoint::coloredpoint(float ox, float oy, unsigned

cout<<"p3dc.display();\n";

p3dc.display();//goi coloredthreedimpoint::Identifier()

getch();

}

Trang 31

Không nhất thiết phải định nghĩa lại hàm ảo

void move(float dx, float dy) {

x += dx;

y += dy;

} };

Trang 32

Không nhất thiết phải định nghĩa lại hàm ảo

class coloredpoint : public point {

unsigned int color;

coloredpoint(float ox, float oy, unsigned int c);

coloredpoint(coloredpoint &b):point((point &)b) {

cout<<"coloredpoint pc(2,3,5);\n"; coloredpoint pc(2,3,5);

Trang 33

Khai báo hàm ảo ở một lớp bất kỳ trong sơ đồ thừa kế

x += dx;

y += dy;

} void Identifier() { cout<<"Diem khong mau \n";

} };

void point::display() { cout<<"Toa do : "<<x<<" "<<y<<endl; Identifier();

}

Trang 34

Khai báo hàm ảo ở một lớp bất kỳ trong sơ đồ thừa kế

class threedimpoint : public point {

} coloredthreedimpoint(float ox, float oy, float oz,unsigned c):

threedimpoint (ox, oy, oz) {

color = c;

} coloredthreedimpoint(coloredthreedimpoint

&p) :threedimpoint(p) { color = p.color;

} void Identifier() { cout<<"Diem mau : "<<color<<endl;

} };

Trang 35

Khai báo hàm ảo ở một lớp bất kỳ trong sơ đồ thừa kế

Trang 36

x = p.x;

y = p.y;

} virtual ~point() { cout<<"point::~point() \n"; }

void display() ; void move(float dx, float dy) {

x += dx;

y += dy;

} virtual void Identifier() { cout<<"Diem khong mau \n"; }

};

Trang 37

} void Identifier() { cout<<"Toa do z : "<<z<<endl;

} };

class coloredthreedimpoint : public threedimpoint { unsigned color;

public:

coloredthreedimpoint() { color = 0;

}

Trang 38

point *p0 = new point(2,10);

point *p1 = new threedimpoint(2,3,5);

point *p2 = new coloredthreedimpoint(2,3,4,10); delete p0;

delete p1;

delete p2;

getch();

}

Trang 39

4.1 Đặt vấn đề

Đa thừa kế cho phép một lớp có thể là dẫn xuất của nhiều lớp cơ sở, do vậy những gì đã đề cập trong phần đơn thừa kế được tổng quát hoá cho trường hợp đa thừa kế Tuy vậy cần phải giải quyết các vấn đề sau:

 Làm thế nào biểu thị được tính độc lập của các thành phần cùng tên bên trong một lớp dẫn xuất?

 Các hàm thiết lập và huỷ bỏ được gọi như thế nào: thứ tự, truyền thông tin v.v.?

 Làm thế nào giải quyết tình trạng thừa kế xung đột trong đó, lớp D dẫn xuất từ B và C, và cả hai cùng là dẫn xuất của A.

Trang 40

4.1 Đặt vấn đề

Ví dụ:

coloredpoint

col point

col ( ) { }

~color() { }void display(){ } };

Trang 41

4.1 Đặt vấn đề

Ví dụ:

Lớp coloredpoint thừa kế từ 2 lớp trên như sau:

class coloredpoint:public point,public col

coloredpoint bị xoá.

Trang 42

4.1 Đặt vấn đề

TRONG HÀM THÀNH PHẦN CỦA LỚP DẪN XUẤT CÓ THỂ SỬ DỤNG TẤT

CẢ CÁC HÀM THÀNH PHẦN public (HOẶC protected ) CỦA LỚP CƠ SỞ.

KHI CÓ NHIỀU HÀM THÀNH PHẦN CÙNG TÊN TRONG CÁC LỚP KHÁC NHAU (ĐỊNH NGHĨA LẠI MỘT HÀM), TA CÓ THỂ LOẠI BỎ SỰ NHẬP

NHẰNG BẰNG CÁCH SỬ DỤNG TOÁN TỬ PHẠM VI “::”

point::display();

col::display();

Trang 43

4.1 Đặt vấn đề

Khai báo

coloredpoint p(3,9,2);

Câu lệnh p.display() gọi tới coloredpoint::display(),

Câu lệnh p.point::display() gọi tới point::display().

Trang 44

class col {

unsigned color;

public:

col(unsigned c) {

cout<<"++Constr col \n"; color=c;

Trang 45

}

~coloredpoint() { cout<<" Destr coloredpoint\n";

} void display() { point::display();

col::display();

} };

void main() {

clrscr();

coloredpoint p(3,9,2); cout<<" -\n"; p.display();

cout<<" -\n"; p.point::display();

cout<<" -\n"; p.col::display();

cout<<" -\n"; getch();

}

Trang 46

4.2 Danh sách móc nối đối tượng

Xây dựng một lớp, cho phép quản lý một danh sách móc nối các đối tượng kiểu point

head là con trỏ đối tượng, chỉ đến phần tử đầu tiên của danh sách móc nối.

Head

Head

Trang 47

4.2 Danh sách móc nối đối tượng

Mỗi phần tử của danh sách chứa:

 Một con trỏ đến phần tử tiếp theo,

 Một con trỏ đến đối tượng chứa thông tin liên quan.

Lớp list để quản lý danh sách sẽ có ít nhất:

 Một thành phần dữ liệu: con trỏ đến phần tử đầu tiên (head),

 Một hàm thành phần có chức năng chèn vào danh sách một đối tượng tại

một địa chỉ nào đó chú ý rằng địa chỉ này phải có kiểu void * để đảm bảo sự

tương thích với các kiểu dữ liệu khác nhau.

Trang 48

4.2 Danh sách móc nối đối tượng

struct element //cấu trúc một phần tử của danh sách

list

{

element *next; //con trỏ đến thành phần đi sau

void *content; //con trỏ đến một đối tượng tuỳ ý

Trang 49

4.2 Danh sách móc nối đối tượng

Để quản lý danh sách ta có thể thêm các chức năng xử lý khác như:

 Hiển thị các đối tượng được chỉ bởi danh sách

 Tìm kiếm một phần tử

 Xoá một phần tử

Các thao tác trên danh sách được nêu ra ở trên đều gắn với cơ chế duyệt danh sách Việc duyệt này cần phải được kiểm soát từ bên ngoài danh sách nhưng có thể dựa trên các thành phần hàm cơ sở là:

 Khởi tạo việc duyệt,

 Chuyển sang phần tử tiếp theo.

Ngày đăng: 16/04/2014, 15:07

TỪ KHÓA LIÊN QUAN

w