1. Trang chủ
  2. » Giáo Dục - Đào Tạo

Bài giảng nguyên lý lập trình hướng đối tượng bài 9 ts lý anh tuấn 1

36 1 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

NGUYÊN LÝ LẬP TRÌNH HƯỚNG ĐỐI TƯỢNG Bài 9: Đa hình Hàm ảo Giảng viên: TS Lý Anh Tuấn Email: tuanla@tlu.edu.vn Nội dung Cơ hàm ảo ◦ ◦ ◦ ◦ Kết gán muộn Thi hành hàm ảo Khi sử dụng hàm ảo Lớp trừu tượng hàm ảo túy Con trỏ hàm ảo ◦ Tương thích kiểu mở rộng ◦ Ép kiểu lên ép kiểu xuống Cơ hàm ảo  Đa hình ◦ Liên kết nhiều ngữ nghĩa với hàm ◦ Hàm ảo cung cấp khả ◦ Là nguyên tắc lập trình hướng đối tượng  Ảo ◦ Tồn chất không dạng thực  Hàm ảo ◦ Có thể sử dụng trước định nghĩa Ví dụ hình vẽ  Lớp kiểu hình vẽ ◦ Hình chữ nhật (rectangle), hình trịn (circle), hình ovan (oval), vân vân ◦ Mỗi hình vẽ đối tượng thuộc lớp khác  Dữ liệu hình chữ nhật: độ cao, chiều rộng, tâm điểm  Dữ liệu hình trịn: tâm điểm, bán kính Tất dẫn xuất từ lớp cha: Figure  Hàm cần có: draw()  ◦ Sư dụng thị khác cho hình vẽ Ví dụ hình vẽ: center() Mỗi lớp cần hàm draw khác  Có thể gọi draw lớp:  Rectangle r; Circle c; r.draw(); //Gọi hàm draw lớp Rectangle c.draw(); // Gọi hàm draw lớp Circle  Lớp cha Figure bao gồm hàm áp dụng cho tất hình vẽ; chẳng hạn: center(): di chuyển hình vẽ vào tâm hình ◦ Xóa hình ban đầu, sau vẽ lại ◦ Do Figure::center() gọi hàm draw để vẽ lại ◦ Vấn đề: Gọi hàm draw() từ lớp nào? Ví dụ hình vẽ: Hình Xét kiểu hình vẽ sau: lớp Triangle dẫn xuất từ lớp Figure  Hàm center() kế thừa từ Figure ◦ Nó có làm việc với hình tam giác khơng? ◦ Nó sử dụng draw() khác với hình ◦ Nó sử dụng Figure::draw()  khơng làm việc với hình tam giác  Cần hàm center() kế thừa sử dụng hàm Triangle::draw() khơng phải hàm Figure::draw() ◦ Nhưng lớp Triangle chí cịn chưa viết viết Figure::center()  Ví dụ hình vẽ: Hình ảo Câu trả lời sử dụng hàm ảo  Nói cho biên dịch:  ◦ Không biết hàm thi hành ◦ Đợi sử dụng chương trình ◦ Khi nhận thi hành từ thể đối tượng  Được gọi kết gán muộn kết gán động ◦ Hàm ảo thi hành kết gán muộn Một ví dụ khác  Chương trình ghi sổ cửa hàng bán phụ tùng ô tô ◦ ◦ ◦ ◦ Theo dõi giao dịch Chưa biết tất giao dịch Ban đầu có giao dịch bán lẻ Sau đó: Giao dịch giảm giá, thư đặt hàng, vân vân  Phụ thuộc vào nhân tố khác bên cạnh giá thuế Hàm ảo: Phụ tùng tơ  Chương trình phải: ◦ Tính tốn tổng doanh thu hàng ngày ◦ Tính tốn giao dịch giá trị lớn nhất/nhỏ ngày ◦ Có thể tính giá trị trung bình giao dịch ngày  Tất đến từ hóa đơn lẻ ◦ Nhưng nhiều hàm tính hóa đơn thêm vào sau  Khi kiểu giao dịch khác thêm vào  Do hàm tính hóa đơn ảo Định nghĩa lớp Sale  class Sale { public: Sale(); Sale(double thePrice); double getPrice() const; virtual double bill() const; double savings(const Sale& other) const; private: double price; }; 10 Tương thích kiểu mở rộng  Biết rằng: Derived lớp dẫn xuất Base ◦ Các đối tượng Derived gán cho đối tượng kiểu Base ◦ Nhưng ngược lại khơng  Xét ví dụ trước: ◦ Một DiscountSale Sale ngược lại khơng 22 Ví dụ tương thích kiểu mở rộng  class Pet { public: string name; virtual void print() const; }; class Dog : public Pet { public: string breed; virtual void print() const; }; 23 Lớp Pet Dog Bây cung cấp khai báo: Dog vdog; Pet vpet;  Lưu ý biến thành viên name breed public  ◦ Chỉ nhằm mục đích ví dụ, khơng điển hình 24 Sử dụng lớp Pet Dog  Một chó thú cưng: ◦ vdog.name = "Tiny"; vdog.breed = "Great Dane"; vpet = vdog; ◦ Những lệnh phép  Có thể gán giá trị cho kiểu cha, ngược lại khơng ◦ Một thú cưng khơng phải chó 25 Vấn đề tách lớp  Lưu ý giá trị gán cho vpet trường breed ◦ coutbreed = "Great Dane"; ppet = pdog;  Không thể truy cập trường breed đối tượng trỏ tới ppet: cout breed; //Khong hop le  28 Ví dụ vấn đề tách lớp  Phải sử dụng hàm thành viên ảo: ppet->print(); ◦ Gọi hàm thành viên print lớp Dog  Bởi ảo  C++ đợi để xem trỏ ppet trỏ tới đối tượng trước gọi kết gán 29 Hàm hủy ảo Nhắc lại: hàm hủy cần để hủy cấp phát liệu cấp phát động  Xét:  Base *pBase = new Derived; … delete pBase; ◦ Sẽ gọi hàm hủy lớp sở trỏ tới đối tượng lớp Derived ◦ Khai báo hàm hủy virtual để khắc phục vấn đề  Có thể để tất hàm hủy ảo 30 Ép kiểu  Xét: Pet vpet; Dog vdog; … vdog = static_cast(vpet); //Không hợp lệ!  Không thể ép thú cưng thành chó, nhưng: vpet = vdog; // Hợp lệ! vpet = static_cast(vdog); //Cũng hợp lệ!  Ép kiểu lên thực ◦ Từ kiểu hậu duệ đến kiểu tổ tiên 31 Ép kiểu xuống  Ép kiểu xuống nguy hiểm ◦ Ép từ kiểu tổ tiên xuống kiểu hậu duệ ◦ Giả sử thơng tin thêm vào ◦ Có thể thực với dynamic_cast: Pet *ppet; ppet = new Dog; Dog *pdog = dynamic_cast(ppet);  Hợp lệ, nguy hiểm  Ép kiểu xuống sử dụng do: ◦ Phải theo dõi tất thông tin thêm vào ◦ Tất hàm thành viên phải ảo 32 Tóm tắt  Kết gán muộn hỗn việc định hàm thành viên gọi chương trình chạy ◦ Trong C++, hàm ảo sử dụng kết gán muộn  Các hàm ảo túy khơng có định nghĩa ◦ Các lớp có hàm ảo túy trừu tượng ◦ Không có đối tượng tạo từ lớp trừu tượng ◦ Được sử dụng làm sở cho lớp khác dẫn xuất 33 Tóm tắt  Đối tượng lớp dẫn xuất gán cho đối tượng lớp sở ◦ Các thành viên lớp sở bị mất: vấn đề tách lớp  Phép gán trỏ đối tượng động ◦ Cho phép khắc phục vấn đề tách lớp  Khai báo tất hàm hủy ảo ◦ Thói quen lập trình tốt ◦ Đảm bảo nhớ hủy cấp phát 34 Bài tập Xây dựng lớp Hinh2D có liệu thành viên màu sắc hai hàm ảo nhap() tinhdientich(), hàm tinhdientich() hàm ảo túy Hàm truy cập hàm biến đổi liệu màu sắc Xây dựng lớp HinhTron, HinhChuNhat, HinhTamGiac kế thừa lớp Hinh2D, đó: - Lớp HinhTron có liệu thành viên mơ tả bán kính hình trịn, lớp HinhChuNhat có hai liệu thành viên mơ tả chiều dài, chiều rộng hình chữ nhật, lớp HinhTamGiac có ba liệu thành viên mơ tả độ dài ba cạnh hình tam giác - Các lớp bao gồm hàm tạo, hàm truy cập, hàm biến đổi ghi đè hai hàm ảo túy lớp cha a) Viết chương trình nhập vào số n danh sách n phần tử gồm hình trịn, hình chữ nhật hình tam giác (do người dùng định lúc nhập) b) In tổng diện tích hình có mảng 35 Gợi ý Khai báo mảng trỏ kiểu Hinh2D, sử dụng toán tử new để tạo đối tượng động thuộc kiểu dẫn xuất khác nhau: Hinh2D *ds[100]; int k=0, chon, i; while(1) { coutchon; cin.ignore(); if (chon==4) break; if (chon==1) ds[k]=new HinhTron(); if (chon==2) ds[k]=new HinhChuNhat(); if (chon==3) ds[k]=new HinhTamGiac(); ds[k]->nhap(); k++; } 36 ... phiên dựa vào đối tượng lớp dẫn xuất ◦ Chúng không tự động sử dụng phiên Sale 12 Định nghĩa lớp dẫn xuất DiscountSale  class DiscountSale : public Sale { public: DiscountSale(); DiscountSale( double... lớp Sale 15 Hàm ảo  Lớp Sale viết trước lớp dẫn xuất DiscountSale ◦ Các hàm thành viên savings “

Ngày đăng: 25/10/2022, 19:57

Xem thêm:

TÀI LIỆU CÙNG NGƯỜI DÙNG

TÀI LIỆU LIÊN QUAN