1. Trang chủ
  2. » Công Nghệ Thông Tin

Bài giảng lập trình hướng đối tượng chương 5 GV dương khai phong

52 146 0

Đ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

Định dạng
Số trang 52
Dung lượng 7,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

 Kiểu kế thừa: private // error // error Do lớp B kế thừa kiểu private nên tính truy cập của các thành viên đƣợc kế thừa từ lớp A sẽ chuyển thành private , mà private chỉ đƣợc phép tru

Trang 1

Số tiết lý thuyết: 45 tiết

Số tiết thực hành: 30 tiết

Trang 2

Chương 1: Tổng quan về OOP

Chương 2: Lớp & đối tƣợng

Chương 3: Hàm và hàm đa năng trong OOP

Chương 4: Đa năng hóa toán tử

Chương 5: Sự kế thừa và tính đa hình

 Nội dung môn học:

Trang 3

 Khái niệm sự kế thừa

 Chương 4: Sự kế thừa và tính đa hình

Trang 4

Khái niệm sự kế thừa

Trang 5

NV_VANPHONG

LCB Phucap

NV_SANXUAT

Sogiolam SoSP

NHANVIEN

MaNV Hoten CMND Nhap() Xuat() Tinhluong()

MaNV Hoten CMND Nhap() Xuat()

MaNV Hoten CMND Nhap() Xuat()

KẾ THỪA

NHÂN

VIÊN

Trang 6

Khái niệm sự kế thừa

Trang 7

Khái niệm sự kế thừa

Lớp A Lớp B

Lớp cơ bản

Lớp dẫn xuất

từ A

Lớp A Lớp B Lớp C Lớp dẫn xuất từ B

Lớp A Lớp B

Lớp C Lớp B Lớp C

Lớp D Lớp A Lớp A

Trang 8

 Khái niệm sự kế thừa

 Chương 4: Sự kế thừa và tính đa hình

Trang 9

Lớp A Lớp B

Lớp cơ bản

Lớp dẫn xuất

từ A

Lớp A Lớp B

Trang 10

class Danxuat: <từ khóa chỉ định kiểu kế thừa> Coban{

… };

class HINH{

private: int mau;

};

class HCN:public HINH{

private: int dai,rong;

};

Trang 11

 Kiểu kế thừa protected: một lớp kế thừa kiểu protected làm

thay đổi tính truy cập các thành viên của lớp cơ bản thành

protected

 Kiểu kế thừa private: một lớp kế thừa kiểu private làm thay

đổi tính truy cập các thành viên của lớp cơ bản thành

private

LỚP

CƠ BẢN

THỪA KẾ PUBLIC

THỪA KẾ PRIVATE

THỪA KẾ PROTECTED

PUBLIC PROTECTED PRIVATE

PUBLIC PROTECTED

NO

PRIVATE PRIVATE

NO

PROTECTED PROTECTED

NO

Trang 12

 Kiểu kế thừa: public

Trang 13

 Kiểu kế thừa: private

// error // error

Do lớp B kế thừa kiểu private nên tính truy cập của các thành viên đƣợc

kế thừa từ lớp A sẽ chuyển thành

private , mà private chỉ đƣợc phép truy xuất bên trong lớp

Trang 14

 Kiểu kế thừa: protected

Do lớp B kế thừa kiểu protected

nên tính truy cập của các thành viên đƣợc kế thừa từ lớp A sẽ chuyển thành protected,

protected chỉ đƣợc phép truy xuất bên trong lớp.và lớp dẫn xuất

Trang 15

Trình tự gọi hàm khởi tạo:

 Khi có kế thừa, trình tự gọi hàm khởi tạo thực hiện theo nguyên tắc: hàm khởi tạo của lớp cơ bản được gọi trước và

lớp dẫn xuất gọi sau

Lưu ý: ta có thể chỉ định hàm khởi tạo nào của lớp cơ bản được

gọi bằng toán tử “:” (xem lại chương 1)

B():A(){ }; // gọi hàm A()

B(int c):A(c){ }; // gọi hàm A(int)

};

Trang 16

Gọi hàm thành viên trong kế thừa:

 Hàm thành viên của lớp dẫn xuất có thể cùng tên với tên hàm thành viên của lớp cơ bản

 Hàm thành viên đƣợc gọi ứng với đối tƣợng gọi nó

<Tên lớp cơ bàn>::<Tên hàm>(…)

Con trỏ trong kế thừa:

Con trỏ lớp cơ bản có thể trỏ tới địa chỉ đối tƣợng của lớp dẫn xuất nhƣng ngược lại thì không

 Đối tƣợng lớp dẫn xuất đƣợc xem nhƣ là một đối tƣợng của lớp cơ bản khi xử lý qua con trỏ nhƣng ngược lại thì không

Trang 17

 Ví dụ trình tự gọi hàm khởi tạo và hàm huỷ trong kế thừa đơn:

base 2 derived 2 Huy derived

Trang 18

 Ví dụ gọi hàm hàm thành viên trong kế thừa:

Cho biết kết quả khi thực thi hàm main() sau:

Y/C: Sửa lại lớp derived để hàm main() xuất ra chữ hello:

Trang 19

 Ví dụ con trỏ trong kế thừa:

Con trỏ lớp dẫn xuất KHÔNG đƣợc phép

tham chiếu đến đối tƣợng lớp cơ bản

Trang 20

 Khái niệm sự kế thừa

 Chương 4: Sự kế thừa và tính đa hình

Trang 21

Kế thừa từ các lớp khác nhau

Kế thừa từ một lớp cơ

bản chung

Trang 22

Lưu ý: Quy tắc về tính truy cập và kiểu thừa

kế trong đa kế thừa cũng giống nhƣ trong kế thừa đơn

class A{

… };

class B{

… };

class C: <từ khóa chỉ định kiểu kế thừa> A, <từ khóa chỉ định kiểu kế thừa> B [, ]{

… };

Trang 24

 Đặc điểm đa kế thừa:

Trình tự gọi hàm khởi tạo:

 Khi có đa kế thừa, trình tự gọi hàm khởi tạo thực hiện theo nguyên tắc sau:

Hàm khởi tạo của lớp cơ bản được gọi trước theo

trình tự từ trái sang phải (liệt kê trong kế thừa)

Nếu trong lớp có chứa các đối tượng là thành viên dữ liệu của lớp thì nó sẽ đƣợc khởi tạo tiếp theo

 Gọi hàm khởi tạo của lớp dẫn xuất

Trình tự gọi hàm huỷ:

 Hàm hủy đƣợc gọi theo trình tự ngƣợc lại:

 Hàm hủy của lớp dẫn xuất

 Hàm hủy của các đối tƣợng

 Hàm hủy của lớp cơ bản

Ví dụ:

Trang 25

 Ví dụ 1: trình tự gọi hàm khởi tạo và hàm huỷ trong đa kế thừa

class C: public A, public B{

public:

C(){cout<<"C"<<endl;}

~C(){cout<<"Huy C"<<endl;}

Trang 26

 Ví dụ 2: trình tự gọi hàm khởi tạo và hàm huỷ trong đa kế thừa khi lớp có chứa các đối tượng là thành viên dữ liệu của lớp

class C: public A, public B{

Trang 27

 Vấn đề trong đa kế thừa:

 Do lớp dẫn xuất thừa kế các thành viên dữ liệu và hàm thành viên từ nhiều lớp nên ta cần phải giải quyết vấn đề trùng lặp

trong đa kế thừa (lỗi mơ hồ: ambiguous)

Ví dụ:

GIAOVIEN

Hoten Luong Nhap(),Xuat()

Kế thừa từ lớp nào?

SINHVIEN

Hoten Lop Nhap(),Xuat()

TROGIANG Hoten ???

Luong, Lop Nhap(),Xuat()

Trang 28

 Vấn đề trong đa kế thừa:

Để giải quyết vấn đề trùng lắp dữ liệu trong đa kế thừa,ta thực hiện một trong các phương pháp sau:

Cách 1: dùng toán tử phạm vi “::” chỉ rõ thành viên dữ liệu hay hàm của lớp nào đƣợc gọi

Cách 2: định nghĩa một hàm cụ thể trong lớp dẫn xuất

Cách 3: nếu kế thừa từ một lớp cơ bản chung thì ta có thể

dùng lớp cơ bản ảo cho việc kế thừa của lớp dẫn xuất theo

cú pháp sau:

Lớp B Lớp C Lớp D Lớp A Lớp A

Lớp B Lớp C Lớp D Lớp A

Trang 29

 Cách 1: dùng toán tử phạm vi “::” chỉ rõ thành viên dữ liệu hay hàm của lớp nào đƣợc gọi

class person{

public: char name[20];

public:

person(){strcpy(name, “chua biet");}

void out(){cout<<"chao "<<name<<endl;}

Trang 30

 Cách 2: định nghĩa một hàm cụ thể trong lớp dẫn xuất

class person{

public: char name[20];

public:

person(){strcpy(name, “chua biet");}

void out(){cout<<"chao "<<name<<endl;}

Trang 31

 Cách 3: sử dụng lớp cơ bản ảo trong kế thừa

class person{

public: char name[20];

public:

person(){strcpy(name, “chua biet");}

void out(){cout<<"chao "<<name<<endl;}

void out(){cout<<"hello "<<name; }

Cho biết kết quả của CT sau:

Trang 32

 Cách 3: sử dụng lớp cơ bản ảo trong kế thừa

 Lợi ích của việc dùng lớp cơ bản ảo khi có kế thừa từ

lớp cơ bản chung:

– Tránh việc gọi hàm khởi tạo của lớp cơ bản nhiều

lần từ lớp dẫn xuất

– Tránh việc trùng lắp các bản sao thành phần dữ

liệu của lớp cơ bản

– Trình tự hàm khởi tạo và hàm hủy khi dùng lớp cơ

bản ảo:

• Hàm khởi tạo của lớp cơ bản ảo được gọi trước

tiên (nếu có nhiều lớp cơ bản ảo thì trình tự bắt đầu từ trên xuống, từ trái sang phải theo đúng trình tự trong cây thư mục kế thừa

• Hàm hủy được gọi theo trình tự ngược lại

Trang 33

 Khái niệm sự kế thừa

 Chương 4: Sự kế thừa và tính đa hình

Trang 34

Tính đa hình trong kế thừa

• Hoặc cùng là đối tƣợng sinh viên nhƣng sinh viên chính qui có thời lƣợng học khác với thời lƣợng học của sinh viên từ xa

Trang 35

Tính đa hình trong kế thừa

 Khái niệm

 Ví dụ

 Cú pháp

 Cú pháp:

Cách thể hiện tính đa hình trong OOP:

 Hàm đa năng là một cách thể hiện tính đa hình trong OOP

Dùng hàm ảo theo cú pháp khai báo sau: dùng từ khóa virtual trước kiểu dữ liệu trả về của hàm:

virtual <Kiểu_data> Tên_hàm(DS_đối số);

 Lưu ý:

• Hàm ảo khi chỉ có khai báo mà không có định nghĩa ngay

trong lớp thì được gọi là hàm thuần ảo (pure virtual)

Cú pháp khai báo như sau:

virtual <Kiểu_data> Tên_hàm(DS_đối số) = 0;

Một lớp nếu có chứa hàm thuần ảo thì được gọi là lớp trừu tượng (abstract class) Lớp trừu tượng là lớp không

Trang 36

 Ví dụ 1: Cho biết kết quả của chương trình sau

Trang 37

 Khắc phục: Để kết quả của chương trình Ví dụ 1 thực thi đúng:

Con trỏ p trỏ vào đối tượng là hinhtron thì dùng hàm ve() của lớp hinhtron

Con trỏ p trỏ vào đối tượng là hinhchunhat thì

Trang 40

Câu 1: Cho biết kết quả của đoạn chương trình sau:

Trang 41

Câu 2: Cho biết kết quả của đoạn chương trình sau:

}

};

A Chương trình báo lỗi

B Kết quả in ra: ABC

C Kết quả in ra: ABB

D Kết quả in ra: BBC

void main() {

Trang 42

Câu 3: Cho biết kết quả của đoạn chương trình sau:

Trang 43

Câu 4: Lớp D là lớp kế thừa public từ lớp B Hàm F là hàm

friend của lớp D Khi đó:

A Hàm F cũng là hàm bạn của lớp B

B Hàm F có thể truy xuất các thành viên có giới hạn private của lớp B

C Hàm F có thể truy xuất các thành viên có giới hạn private của lớp B và D

D Hàm F có thể truy xuất các thành viên có giới hạn private của lớp D

Trang 44

Câu 5: Phát biểu nào sau đây là SAI:

A Lớp dẫn xuất có thể khởi tạo giá trị khác cho các thuộc tính có giới hạn public của

lớp cơ sở

B Destructor của lớp cơ sở được gọi sau destructor của lớp dẫn xuất

C Nếu một lớp dẫn xuất không có cài đặt hàm destructor của lớp cơ sở cũng sẽ

không được gọi khi giải phóng đối tượng thuộc lớp dẫn xuất

D Constructor của lớp cơ sở được gọi trước constructor của lớp dẫn xuất

Trang 45

Câu 6: Phát biểu nào sau đây là SAI:

A Hàm ảo của lớp phải đƣợc cài đặt trong lớp đó

B Hàm ảo trong lớp cơ sở có thể đƣợc viết lại trong lớp dẫn xuất

C Hàm ảo khác với hàm thuần ảo

D Hàm ảo của một lớp có thể là hàm friend của lớp đó

Trang 46

Câu 7: Sự khác nhau giữa hàm ảo (virtual) và hàm thuần ảo

(pure virtual):

A Hàm thuần ảo không có phần cài đặt

B Hàm thuần ảo phải có khai báo từ khoá pure virutal

C Hàm ảo và hàm thuần ảo là giống nhau

D Một lớp hoặc chỉ có hàm thuần ảo hoặc chỉ có hàm ảo

Trang 47

Câu 8: Cho biết kết quả của đoạn chương trình sau:

C Chương trình báo lỗi

D Màn hình xuất hiện: A=5

Trang 48

Câu 9: Cho biết kết quả của đoạn chương trình sau:

A Chương trình chạy và hiển thị ký tự C trên màn hình

B Chương trình chạy và không hiển thị kết quả gì

C Chương trình báo lỗi do khai báo biến con trỏ pb thuộc kiểu lớp trừu tượng

D Chương trình báo lỗi do khai báo biến c thuộc kiểu lớp trừu tượng

Trang 49

Câu 10: Cho biết kết quả của đoạn chương trình sau:

class Base{

public:

Base(){ cout<<"Base class " <<endl;}

};

class Derive: Base {

Derive(){ cout<<"Derive class " <<endl;}

A Base class Derive class

B Derive class Base class

C Base class Base class Derive class

D Base class Derive class Base class

Trang 51

ĐÁP ÁN:

1 B Do obj là con trỏ thuộc lớp a nên sẽ sủ dụng hàm func() của lớp a

2 B Câu lệnh pb ->A::In() cho biết con trỏ pb cần gọi hàm In() của lớp A

3 D x: thuộc phạm vi public nên kế thừa, y: thuộc protected nên cũng đƣợc kế thừa, z là thành phần thuộc lớp C nên đƣợc sử dụng

Đáp án A sai vì hàm bạn không có tính chất bắc cầu  hàm F không liên quan tới lớp B  B,C sai do hàm F không thể truy xuất

dữ liệu thuộc private của B

5 C Hàm huỷ đƣợc gọi một cách tự động trong kế thừa mà không phụ thuộc vào việc có cài đặt hay không?

Trang 52

ĐÁP ÁN:

6 D Hàm ảo phải là hàm thành viên của lớp

7 A Các khái niệm B,D,C là những khái niệm SAI

8 D Câu lệnh d.BaseA::Print(); đã xác định rõ hàm Print() là của lớp A

9 A pb là con trỏ lớp cơ bản nên có thể trỏ tới đối tượng là lớp dẫn xuất nhưng ngược lại thì không

Derive d;

d là đối tượng lớp dẫn xuất nên trỉnh tự gọi hàm khởi tạo: lớp cơ bản gọi trước, lớp dẫn xuất gọi sau

Ngày đăng: 04/12/2015, 14:37

TỪ KHÓA LIÊN QUAN

🧩 Sản phẩm bạn có thể quan tâm