intTypePromotion=1
zunia.vn Tuyển sinh 2024 dành cho Gen-Z zunia.vn zunia.vn
ADSENSE

Ngôn ngữ lập trình C - Chương 7

Chia sẻ: Nguyen Nhi | Ngày: | Loại File: PDF | Số trang:0

83
lượt xem
11
download
 
  Download Vui lòng tải xuống để xem tài liệu đầy đủ

Tài liệu tham khảo bài giảng về Ngôn ngữ lập trình C++ gồm 7 chương - Chương 7 Thừa kế và đa hình

Chủ đề:
Lưu

Nội dung Text: Ngôn ngữ lập trình C - Chương 7

  1. Ch−¬ng 7 Ch Thõa kÕ vμ ®a h×nh
  2. 7.1 Tæng quan vÒ thõa kÕ vµ ®a h×nh 7.1.1 Thừa kế trong lập trình HĐT – Khái niệm • Thừa kế là một trong ba nguyên tắc cơ bản của LTHĐT. • Lớp cơ sở và lớp dẫn xuất: – Lớp được thừa kế lớp cơ sở, lớp thừa kế lớp dẫn xuất. – Một lớp có thể là lớp cơ sở cho nhiều lớp dẫn xuất. – Một lớp dẫn xuất có thể là lớp cơ sở cho một lớp khác. • Sự thừa kế trong lớp dẫn xuất: – 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 vào các thành phần mới. • Lớp dẫn xuất sẽ “làm tốt hơn” (hoặc “làm lại”) những công việc mà lớp cơ sở “làm chưa tốt” (hoặc không còn “phù hợp” với lớp dẫn xuất). – Lớp cơ sở thường được xử lý giống như một thành phần có kiểu là đối tượng ( khái niệm kết tập). 2 Bài giảng C++. 19/11/2008 V.S.Nam. B/m KTHT, khoa CNTT, ĐHXD
  3. 7.1 Tæng quan vÒ thõa kÕ vµ ®a h×nh 7.1.1 Thừa kế trong lập trình HĐT – Đặc điểm • Thừa kế cho phép tạo kiểu mới trên cơ sở lớp đang tồn tại. – Mở rộng chúng với những thuộc tính mới tạo đối tượng giống một phần đối tượng cũ. • Thừa kế cho phép nâng cao khả năng sử dụng lại chương trình. – Không phải biên dịch lại các thành phần chương trình đã có trong các lớp cơ sở. Không cần phải có chương trình nguồn tương ứng: người lập trình được phép thừa kế các lớp định nghĩa trước đó. Người dùng hoàn toàn không thể và không cần phải biết rõ phần chương trình nguồn tương ứng. • Trình dịch có thể cung cấp một thư viện lớp, đối tượng làm cơ sở để xây dựng giao diện ứng dụng. 3 Bài giảng C++. 19/11/2008 V.S.Nam. B/m KTHT, khoa CNTT, ĐHXD
  4. 7.1 Tæng quan vÒ thõa kÕ vµ ®a h×nh 7.1.2 Đa hình trong lập trình hướng đối tượng – Khái niệm • Đa hình là một trong ba nguyên tắc cơ bản của LTHĐT. – Tính đa hình được thiết lập trên cơ sở thừa kế. • Đa hình: đối tượng có thể có biểu hiện khác nhau tuỳ thuộc tình huống cụ thể. – Tính đa hình có thể thể hiện trên một hành vi (phương thức của lớp) hoặc trên toàn bộ đối tượng. – Tính đa hình cung cấp khả năng xử lý các lớp liên hệ nhau của các đối tượng theo một cách tổng quát. – Định nghĩa lại hàm thành phần • Định nghĩa lại HTP của lớp cơ sở trong lớp dẫn xuất là cơ sở cho việc thiết đặt tính đa hình. • Phân biệt định nghĩa lại và định nghĩa chồng (xem chương 4 & 6) 4 Bài giảng C++. 19/11/2008 V.S.Nam. B/m KTHT, khoa CNTT, ĐHXD
  5. 7.2 Thõa kÕ 7.2.1 Thừa kế lớp – Cú pháp định nghĩa thừa kế class Lop_TK : access Lop_CS { //Khai báo và định nghĩa các thành phần mới [dữ liệu thành phần mới] [hàm thành phần mới] }; – Chú ý: • access: thuộc tính thừa kế – Là một trong ba thuộc tính: public, private, protected. • Lop_CS : lớp cơ sở (là lớp có trước). • Lop_TK : lớp thừa kế trực tiếp - lớp dẫn xuất (là lớp được định nghĩa trên cơ sở của lớp B). 5 Bài giảng C++. 19/11/2008 V.S.Nam. B/m KTHT, khoa CNTT, ĐHXD
  6. 7.2 Thõa kÕ 7.2.1 Thừa kế lớp – Thành phần của lớp dẫn xuất • DLTP : lớp dẫn xuất thừa kế tất cả DLTP của lớp cơ sở. • HTP : lớp dẫn xuất thừa kế tất cả HTP của lớp cơ sở trừ hàm tạo, hàm hủy, hàm bạn và hàm phép toán gán. – Truy nhập thành phần • 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 (thành phần, hàm bạn và đối tượng). • HTP của lớp dẫn xuất được phép truy nhập đến các thành phần protected và public của lớp cơ sở. Phạm vi lớp chỉ mở rộng cho hàm bạn, lớp bạn mà không được mở rộng đến các lớp thừa kế. 6 Bài giảng C++. 19/11/2008 V.S.Nam. B/m KTHT, khoa CNTT, ĐHXD
  7. 7.2 Thõa kÕ 7.2.1 Thừa kế lớp – Thuộc tính thừa kế • Dẫn xuất public: không thay đổi thuộc tính của các thành phần thừa kế từ lớp cơ sở. • Dẫn xuất protected: – Thành phần public, protected trong lớp cơ sở thành phần protected trong lớp dẫn xuất. – Thành phần private của lớp cơ sở thành phần private trong lớp dẫn xuất. • Dẫn xuất private: – Tất cả thành phần của lớp cơ sở (public, protected, private) thành phần private trong lớp dẫn xuất. – Dẫn xuất private được dùng khi không cần khai báo thêm HTP mới mà chỉ định nghĩa lại các hàm đã có trong lớp cơ sở. 7 Bài giảng C++. 19/11/2008 V.S.Nam. B/m KTHT, khoa CNTT, ĐHXD
  8. 7.2 Thõa kÕ 7.2.1 Thừa kế lớp – Định nghĩa lại thành phần (dữ liệu, hàm) • Đặt tên DLTP trong lớp dẫn xuất trùng tên DLTP trong lớp cơ sở. – DLTP mới sẽ “che khuất” DLTP của lớp cơ sở. – Có thể truy nhập tới thành phần trong lớp cơ sở theo cú pháp: tên_lớp::tên_thành_phần; • Định nghĩa lại hàm thành phần. – Hàm định nghĩa lại giống hàm nguyên thủy cả về tên, tham số và giá trị trả về. – Các hàm này chỉ khác nhau ở vị trí: một hàm nằm trong lớp dẫn xuất và hàm kia nằm trong lớp cơ sở. • Tránh định nghĩa chồng hàm trong phân cấp thừa kế. – Các hàm trùng tên ở lớp cơ sở sẽ bị “che khuất”. 8 Bài giảng C++. 19/11/2008 V.S.Nam. B/m KTHT, khoa CNTT, ĐHXD
  9. 7.2 Thõa kÕ 7.2.1 Thừa kế lớp – Tính thừa kế trong lớp dẫn xuất • Đối tượng lớp dẫn xuất và lớp cơ sở. – 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ó thể chuyển kiểu ngầm định từ một đối tượng của lớp dẫn xuất sang một đối tượng của lớp cơ sở. – VD: Lop_TK: dt_tk; Lop_CS: dt_cs = dt_tk; – Điều ngược lại không đúng nếu không định nghĩa chồng phép toán gán trên lớp cơ sở và lớp dẫn xuất. • Con trỏ, tham chiếu lớp dẫn xuất và lớp cơ sở. – Con trỏ (tham chiếu) lớp cơ sở có thể trỏ đến đối tượng lớp dẫn xuất. – Con trỏ (tham chiếu) lớp dẫn xuất không thể nhận địa chỉ (gán giá trị) của đối tượng lớp cơ sở (trừ trường hợp ép kiểu). 9 Bài giảng C++. 19/11/2008 V.S.Nam. B/m KTHT, khoa CNTT, ĐHXD
  10. 7.2 Thõa kÕ 7.2.2 Hàm tạo, hàm hủy và tính thừa kế – Hàm tạo trong lớp dẫn xuất • Lớp dẫn xuất không thể thừa kế hàm tạo của lớp cơ sở. • Cơ chế chung gọi hàm tạo của lớp dẫn xuất: – Gọi hàm tạo của lớp cơ sở. DLTP thừa kế từ lớp cơ sở được khởi tạo trước. – Gọi hàm tạo của lớp dẫn xuất. Phần còn lại của đối tượng được khởi tạo. • Như vậy, hàm tạo lớp cơ sở luôn được gọi trước khi DLTP trong lớp dẫn xuất được khởi tạo và trước khi thực thi các lệnh khác. – Cơ chế trên được thực hiện một cách ngầm định, không cần phải gọi tường minh hàm tạo của lớp cơ sở trong hàm tạo của lớp dẫn xuất. – Trong thực tế cũng không thể thực hiện được việc gọi hàm tạo của một lớp nào đó một cách tường minh. 10 Bài giảng C++. 19/11/2008 V.S.Nam. B/m KTHT, khoa CNTT, ĐHXD
  11. 7.2 Thõa kÕ 7.2.2 Hàm tạo, hàm hủy và tính thừa kế – Hàm tạo trong lớp dẫn xuất (tiếp) • C++ cho phép gọi tới một trong các hàm tạo lớp cơ sở trong định nghĩa của hàm tạo lớp dẫn xuất. – Cú pháp chung: Lop_TK(ds_tham_số) : Lop_CS(ds_giá_trị) { //... } – D là hàm tạo lớp dẫn xuất. – B là hàm tạo lớp cơ sở. • Một số chú ý khi định nghĩa hàm tạo của lớp dẫn xuất: – Có thể không cần mô tả lời gọi hàm tạo của lớp cơ sở trong định nghĩa hàm tạo của lớp dẫn xuất. – Có thể thay đổi tham số truyền cho hàm tạo lớp cơ sở. 11 Bài giảng C++. 19/11/2008 V.S.Nam. B/m KTHT, khoa CNTT, ĐHXD
  12. 7.2 Thõa kÕ 7.2.2 Hàm tạo, hàm hủy và tính thừa kế – Hàm tạo trong lớp dẫn xuất (tiếp) • Lời gọi tới hàm tạo ngầm định của lớp cơ sở được sinh ra một cách tự động. – Nếu lớp cơ sở không có hàm tạo ngầm định, một trong các hàm tạo của lớp cơ sở trong danh sách khởi tạo của hàm tạo của lớp dẫn xuất phải được gọi. – Nếu không định nghĩa hàm tạo cho lớp dẫn xuất trình dịch tự động tạo ra một hàm tạo ngầm định. • Trình tự khởi tạo DLTP của đối tượng lớp dẫn xuất: – Đặt chỗ cho đối tượng (trạng thái chưa được xác định cụ thể). – Hàm tạo tương ứng của lớp cơ sở được gọi (ngầm định hoặc qua danh sách khởi tạo của hàm tạo lớp dẫn xuất). – Hàm tạo của lớp dẫn xuất được gọi để bổ sung DLTP mới. 12 Bài giảng C++. 19/11/2008 V.S.Nam. B/m KTHT, khoa CNTT, ĐHXD
  13. 7.2 Thõa kÕ 7.2.2 Hàm tạo, hàm hủy và tính thừa kế – Hàm tạo sao chép trong lớp dẫn xuất • Trong định nghĩa của HTSC lớp dẫn xuất có thể mô tả bất kỳ hàm tạo nào có mặt trong lớp cơ sở. • Cú pháp chung: Lop_TK(Lop_TK &dt_tk) : Lop_CS(ds_giá_trị) { //... } • Có thể sử dụng một cách làm khác: gọi HTSC của lớp cơ sở trong định nghĩa của HTSC lớp dẫn xuất. – Cú pháp: Lop_TK(Lop_TK &dt_tk) : Lop_CS((Lop_CS &)dt_cs) { // hoặc gọn hơn: D(D &d) : B(b) } 13 Bài giảng C++. 19/11/2008 V.S.Nam. B/m KTHT, khoa CNTT, ĐHXD
  14. 7.2 Thõa kÕ 7.2.2 Hàm tạo, hàm hủy và tính thừa kế – Hàm hủy trong lớp dẫn xuất • Lớp dẫn xuất không thể thừa kế hàm hủy của lớp cơ sở. • Cơ chế chung gọi hàm hủy: – Khi đối tượng thuộc lớp dẫn xuất được giải phóng các đối tượng thành phần và các đối tượng thừa kế từ lớp cơ sở cũng bị giải phóng theo hàm hủy sẽ được gọi đến. – Chỉ cần quan tâm tới các DLTP trong lớp dẫn xuất, không cần để ý đến đối tượng thành phần và DLTP thừa kế từ lớp cơ sở. 14 Bài giảng C++. 19/11/2008 V.S.Nam. B/m KTHT, khoa CNTT, ĐHXD
  15. 7.3 §a h×nh 7.3 7.3.1 Hàm ảo và tính đa hình – Đa hình: • Đối tượng có thể biểu hiện khác nhau tuỳ thuộc tình huống cụ thể. – Gắn kết tĩnh/động: • Vấn đề: con trỏ kiểu lớp cơ sở có thể nhận địa chỉ của đối tượng thuộc lớp dẫn xuất. nảy sinh vấn đề : xác định HTP cụ thể tuỳ thuộc vào thời điểm tham chiếu đối tượng như thế nào? • Gắn kết tĩnh (sớm): xác định HTP trong quá trình biên dịch. – Trong gắn kết tĩnh, việc gọi HTP được xác định trước trong chương trình và không thay đổi trong khi thực thi. • Gắn kết động (muộn): xác định HTP trong quá trình thực thi. – Trong gắn kết động, việc gọi HTP được xác định khi thực thi chương trình dựa trên đối tượng mà con trỏ đang chứa địa chỉ. 15 Bài giảng C++. 19/11/2008 V.S.Nam. B/m KTHT, khoa CNTT, ĐHXD
  16. 7.3 §a h×nh 7.3 7.3.1 Hàm ảo và tính đa hình – Hàm ảo và tính đa hình • C++ sử dụng hàm ảo để thực thi gắn kết động. – Để thực hiện gắn kết động, ta khai báo hàm liên quan là hàm ảo bằng từ khóa virtual. • 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. – Khi gọi hàm ảo, kiểu gắn kết động của đối tượng thực sẽ quyết định gọi hàm nào. – Khi gọi hàm bình thường (không phải là hàm ảo), kiểu gắn kết tĩnh của đối tượng thực sẽ quyết định gọi hàm nào. • Hạn chế đối với hàm ảo: – Hàm bạn không thể là hàm ảo, nhưng một hàm ảo của một lớp có thể khai báo friend trong một lớp khác. 16 Bài giảng C++. 19/11/2008 V.S.Nam. B/m KTHT, khoa CNTT, ĐHXD
  17. 7.3 §a h×nh 7.3 7.3.1 Hàm ảo và tính đa hình – Hàm ảo và tính đa hình (tiếp) • Lớp chứa ít nhất một hàm ảo hoặc thừa kế ít nhất một hàm ảo được gọi là lớp đa hình. – Tính đa hình còn thể hiện khi một HTP trong lớp cơ sở được gọi từ một đối tượng lớp dẫn xuất, còn bản thân HTP đó thì gọi tới HTP được định nghĩa đồng thời trong cả lớp cơ sở (khai báo virtual có mặt ở đây) và trong các lớp dẫn xuất. • Định nghĩa lại hàm ảo: – Nếu hàm trong lớp dẫn xuất khác hàm trong lớp cơ sở (về kiểu trả về hoặc danh sách tham số), từ khoá virtual sẽ bị bỏ qua. • Trình dịch sẽ coi hàm trong lớp dẫn xuất là hàm bình thường. – Không cần thiết phải có từ khóa virtual khi định nghĩa lại hàm ảo trong lớp dẫn xuất. • Thông thường ta nên ghi rõ nhằm mục đích tường minh, trừ trường hợp hàm đã được định nghĩa hoàn chỉnh trong lớp cơ sở. 17 Bài giảng C++. 19/11/2008 V.S.Nam. B/m KTHT, khoa CNTT, ĐHXD
  18. 7.3 §a h×nh 7.3 7.3.1 Hàm ảo và tính đa hình – Hàm ảo trong phân cấp lớp • Phạm vi của khai báo virtual: – Khi hàm được khai báo virtual ở trong một lớp cơ sở, hàm đó được xem như thể hiện của gắn kết động trong lớp cơ sở đó và trong tất cả các lớp dẫn xuất từ nó. • Có thể khai báo hàm ảo ở một lớp bất kì trong sơ đồ thừa kế: – Nếu một hàm được khai báo bình thường ở lớp cơ sở nhưng lại được khai báo ảo ở lớp dẫn xuất trình dịch sẽ xem chúng có kiểu gắn kết khác nhau. • Hàm ở lớp cơ sở được coi là có kiểu gắn kết tĩnh, còn hàm ở lớp dẫn xuất được coi là có kiểu gắn kết động. – Lớp “cơ sở” và lớp “dẫn xuất” ở đây được hiểu rộng hơn, xét trên cây thừa kế. 18 Bài giảng C++. 19/11/2008 V.S.Nam. B/m KTHT, khoa CNTT, ĐHXD
  19. 7.3 §a h×nh 7.3 7.3.2 Các vấn đề khác về hàm ảo – Định nghĩa chồng hàm ảo • Có thể định nghĩa chồng một hàm ảo – Nếu định nghĩa một hàm ảo trong một lớp và định nghĩa chồng nó trong một lớp dẫn xuất với các tham số khác trình dịch coi hàm định nghĩa chồng đó là một hàm hoàn toàn khác, không liên quan gì đến hàm ảo hiện tại nếu nó không được khai báo virtual thì nó có tính chất gắn kết tĩnh. – Nói chung, nếu định nghĩa chồng hàm ảo thì tất cả các hàm định nghĩa chồng của nó nên khai báo là virtual để việc xác định lời gọi hàm đơn giản hơn. 19 Bài giảng C++. 19/11/2008 V.S.Nam. B/m KTHT, khoa CNTT, ĐHXD
  20. 7.3 §a h×nh 7.3 7.3.2 Các vấn đề khác về hàm ảo – Hàm huỷ ảo • Hàm tạo không thể là hàm ảo, trong khi đó hàm huỷ thì có thể. • Xét trường hợp các đối tượng trong cây thừa kế được cấp phát động. – Lúc này hàm hủy của lớp cơ sở được gọi mà không cần biết đến kiểu của đối tượng (là đối tượng mà con trỏ trỏ đến), ngoài ra nó cũng không biết đến tên hàm huỷ của lớp tương ứng với đối tượng mặc dù nó có thể khác với hàm huỷ của lớp cơ sở. • Giải pháp cho vấn đề này là khai báo hàm huỷ ảo cho lớp cơ sở. – Khi đó hàm huỷ của các lớp dẫn xuất là ảo mà không yêu cầu chúng phải có cùng tên. Ta gọi đây là tính đa hình của hàm ảo. 20 Bài giảng C++. 19/11/2008 V.S.Nam. B/m KTHT, khoa CNTT, ĐHXD
ADSENSE

CÓ THỂ BẠN MUỐN DOWNLOAD

 

Đồng bộ tài khoản
2=>2