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

Bài giảng Lập trình hướng đối tượng: Bài 7 - Phạm Thị Bích Vân

Chia sẻ: Estupendo Estupendo | Ngày: | Loại File: PPTX | Số trang:16

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

Bài 7 cung cấp kiến thức về đa hình trong lập trình hướng đối tượng. Nội dung trình bày trong chương này gồm có: Các phương thức ảo, lớp cơ sở trừu tượng, các thành viên ảo của một lớp,... Mời các bạn cùng tham khảo để biết thêm các nội dung chi tiết.

Chủ đề:
Lưu

Nội dung Text: Bài giảng Lập trình hướng đối tượng: Bài 7 - Phạm Thị Bích Vân

  1. Bài 7: Đa hình
  2. Giới thiệu •   Đa hình là khả năng cho phép: •     Cho  phép  các  lớp  được  định  nghĩa  các  phương  thức  trùng  nhau: cùng tên, cùng số lượng và kiểu tham số, cùng kiểu trả  về.  Việc  định  nghĩa  phương  thức  trùng  nhau  của  các  lớp  kế  thừa nhau còn được gọi là sự nạp chồng phương thức. •   Khi gọi các phương thức trùng tên, dựa vào  đối tượng  đang  gọi mà chương trình sẽ thực hiện phương thức của lớp tương  ứng, và do đó, sẽ cho các kết quả khác nhau. •   Ví dụ: Xây dựng lớp người, lớp sinh viên, lớp giáo viên cùng  có phương thức Nhap() và phương thức Xuat().  Như vậy  đa hình là khả năng cho phép viết chương trình  để xử lý  tổng  quát  các  đối  tượng  của  tất  cả  các  lớp  trong  một  phân  cấp  như  các  đối tượng của lớp cơ sở. Do vậy một thông  điệp  được gửi  đi mà  không cần biết đối tượng nhận thuộc lớp nào. 
  3. Các phương thức ảo •   Xét ví dụ 3 lớp A,B,C đều có phương thức xuat() A  *p, *q, *r;   // p, q, r là con trỏ kiểu A A   a;    //  a là đối tượng kiểu A B   b;    //  b là đối tượng kiểu B C   c;    //  c là đối tượng kiểu c //­­­­­­­­­­­­­­­­­ p =  &a ; q =  &b ; r =   &c ; //­­­­­­­­­­­­ p­>xuat(); q­>xuat(); r­>xuat(); ⇒ Cả ba câu lệnh đều gọi đến A::xuat() ⇒ Giải pháp:  Xây dựng xuat() là phương thức ảo
  4. Các phương thức ảo •   Giả sử A là lớp cơ sở. •   B,C,D là lớp dẫn xuất. •   Giả sử các lớp này đều có phương thức xuat(). •   Để định nghĩa các phương thức này là ảo có 2 cách: o     Hoặc  thêm  từ  khoá  virtual  vào  dòng  tiêu  đề  của  phương thức bên trong định nghĩa lớp cơ sở A. o     Hoặc  thêm  từ  khoá  virtual  vào  dòng  tiêu  đề  bên  trong định nghĩa của  tất cả các lớp A, B, C và D
  5. Các phương thức ảo •   Khi  xây  dựng  một  cấu  trúc  cây  phân  cấp,  người  lập  trình chuẩn bị các hành vi chung của lớp đó. •   Hành  vi  giao  tiếp  chung  sẽ  được  dùng  để  thể  hiện  cùng hành vi, nhưng có các hành động khác nhau   đó  là phương thức ảo.   Ví dụ: Đọc thêm ví dụ trang 122 ­ giáo trình LTHĐT
  6. Các phương thức ảo class Base class Derived : public Base { {        public:      public:             virtual void Display()           virtual void Display()            {          {                 cout
  7. Các phương thức ảo •   Kết quả khi chạy chương trình: •   Giải thích: •    Nếu không có khai báo virtual cho phương thức  Base::Display()  khi đó lệnh Show(D) trong hàm main() sẽ gọi đến  Base::Display()  (vì đối tượng của lớp dẫn xuất cũng là đối tượng của lớp cơ sở). • Nhờ  khai  báo  virtual  cho  phương  thức  Base::Display()  nên  sẽ  không thực hiện gọi phương thức  Base::Display() một cách cứng  nhắc trong hàm Show() mà tùy thuộc vào kiểu của tham số vào lúc  chạy  chương  trình.  (  khi  truyền  tham  số  B  thì  Base::Display()  được gọi, khi truyền D thì Derived::Display() được gọi). 
  8. Các phương thức ảo •  Giải thích cơ chế: •  Khi nhận thấy có khai báo virtual trong lớp cơ sở, trình biên  dịch  sẽ  thêm  vào  mỗi  đối  tượng  của  lớp  cơ  sở  và  lớp  dẫn  xuất  của  nó  một  con  trỏ  chỉ  đến  bảng  phương  thức  ảo  (virtual function table), con  trỏ có tên vptr. •  Bảng phương thức  ảo là nơi chứa các con trỏ chỉ đến đoạn  chương trình đã biên dịch ứng với các phương thức ảo.  •  Mỗi lớp có một bảng phương thức ảo.  •  Trình biên dịch chỉ lập bảng phương thức ảo khi bắt đầu có  việc  tạo  đối  tượng  của  lớp.  Đến  khi  chương  trình  chạy,  phương  thức  ảo  của  đối  tượng  mới  được  nối  kết  và  thi  hành thông qua con trỏ vptr
  9. Các phương thức ảo •  Giải thích cơ chế: •   Xét ví dụ trên: Hàm Show(D). •     Đối  tượng  D  thuộc  lớp  Derived  tuy  bị  chuyển  đổi  kiểu  thành  một  đối  tượng  thuộc  lớp  Base  nhưng  nó  không  hoàn  toàn giống một đối tượng của Base chính cống như B.  •   Con trỏ vptr trong  B chỉ đến vị trí trên bảng phương thức  ảo  ứng  với  phương  thức  Base::Display(),  trong  khi  con  trỏ  vptr  trong  D  vẫn  còn  chỉ  đến  phương  thức  Derived::Display() cho dù D bị chuyển kiểu thành Base.      Do  vậy  lệnh:  Show(D);gọi  đến  phương  thức  Derived::Display()
  10. Các phương thức ảo •  Đặc trưng của phương thức ảo. •  Phương thức ảo không thể là các phương thức tĩnh. •   Không  cần  thiết  phải  ghi  rõ  từ  khóa  virtual  trước  định nghĩa một phương thức ảo trong lớp dẫn xuất. •  Khi một phương thức được định nghĩa là  ảo, từ lớp  cơ  sở  đến  lớp  dẫn  xuất  đều  phải  định  nghĩa  thống  nhất  về  tên,  kiểu  trả  về  và  danh  sách  các  tham  số.  Nếu  ta  sơ  xuất  định  nghĩa  phương  thức  khác  đi  thì  trình biên dịch sẽ hiểu đó là phương thức khác.
  11. Lớp cơ sở trừu tượng •  Trong quá trình thiết kế hướng đối tượng, để tạo hệ thống phả  hệ mang tính kế thừa cao người lập trình phải đoán trước sự phát  triển của cấu trúc từ đó lựa chọn những thành viên phù hợp cho  lớp trên cùng.  •   Để tránh tình trạng xây dựng các đối tượng lãng phí bộ nhớ, C++  cho phép thiết kế các lớp có các phương thức ảo không làm gì cả,  và cũng không thể tạo ra đối tượng của lớp đó.  Những lớp như vậy gọi là lớp trừu tượng.
  12. Lớp cơ sở trừu tượng •   Là lớp chỉ dùng làm cơ sở cho các lớp khác. •   Không được khởi tạo một đối tượng thuộc lớp trừu  tượng. •   Các phương thức của lớp trừu tượng là các phương  thức ảo thuần túy. virtual  void  tên_phương_thức() = 0 ; •   Bất kỳ lớp nào dẫn xuất từ một lớp cớ sở trừu tượng  phải định nghĩa lại tất cả các phương thức thuần ảo mà  nó thừa hưởng.
  13. Lớp cơ sở trừu tượng •   Trong cây phân cấp trên không phải lớp nào cũng cần hàm print(),  nhưng nó được tạo ra ở khắp nơi để tạo bộ mặt chung cho mọi lớp của  cây  phân cấp. •   A::Print() thường là phương thức ảo để có được tính đa hình.
  14. Lớp cơ sở trừu tượng •  Khi đó với hàm void Show(A* a) { a­>Print(); } ta  có thể truyền  đối  tượng  đủ kiểu cho nó (A, B,  C,  D hoặc  E) mà  vẫn  gọi  đến  đúng  phuơng  thức  Print()  phù  hợp,  dù  kiểu  của  đối  tượng lúc biên dịch vẫn còn chưa biết. •   Để  tránh  trình  trạng  vô  tình  tạo  ra  đối  tượng  thuộc  lớp  A,  ta  thường  xây  dựng  lớp  trừu  tượng  với  các  phương  thức  thuần  ảo  (pure virtual function) như sau: class A { public:       virtual void Print() = 0; };
  15. Lớp cơ sở trừu tượng Ø Chú ý: •   Chúng ta không thể tạo ra một đối tượng của lớp trừu tượng,  nhưng hoàn toàn có thể tạo ra một con trỏ trỏ đến lớp này (vì  con trỏ không phải là đối tượng thuộc lớp) hoặc là một tham  chiếu. •    Nếu trong lớp kế thừa từ lớp trừu tượng chúng ta không định  nghĩa  phương  thức  thuần  ảo,  do  tính  kế  thừa  nó  sẽ  bao  hàm  phương thức thuần ảo của lớp cơ sở, nên lớp dẫn xuất này sẽ  trở thành lớp trừu tượng. •    Theo định nghĩa lớp trừu tượng, nếu trong lớp dẫn xuất (từ  lớp  cơ  sở  trừu  tượng)  chúng  ta  định  nghĩa  thêm  một  phương  thức thuần ảo khác, lớp này cũng sẽ trở thành lớp trừu tượng.
  16. Các thành viên ảo của một lớp •   Các toán tử ảo: •   Các toán tử bản chất cũng là các phương thức nên ta có thể định  nghĩa các toán tử là ảo, chú ý kiểu của toán hạng phải sử dụng  kiểu của lớp cơ sở gốc có toán tử ảo. •   Ví dụ class A { … virtual A& operator + (A& T); virtual A& operator = (A& T); …   } Class B: public A {… virtual A& operator + (A& T); virtual A& operator = (A& T); …   }
ADSENSE

CÓ THỂ BẠN MUỐN DOWNLOAD

 

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