Bài 9: Kế thừa (Inheritance) EE3490: Kỹ thuật lập trình HK1 2017/2018 TS. Đào Trung Kiên ĐH Bách khoa Hà Nội

Similar documents
Khối: Cao Đẳng nghề và Trung Cấp Năm 2009

Chương 5. Network Layer 19/09/2016 1

BÀI TẬP THỰC HÀNH LẬP TRÌNH WINDOWS C#

Kỹ thuật thu nhỏ đối tượng trong Design (Layout)

Chương 5. Network Layer. Phần 1 - Địa chỉ IPv4. Tài liệu : Forouzan, Data Communication and Networking

Bộ môn HTMT&TT, Khoa Công Nghệ Thông Tin và TT, ĐH Cần Thơ

Internet Protocol. Bởi: Phạm Nguyễn Bảo Nguyên

Hướng dẫn cài đặt FPT

Cài đặt và cấu hình StarWind iscsi trên Windows. iscsi SAN là gì?

HƯỚNG DẪN SỬ DỤNG HỆ THỐNG CẬP NHẬT CHỨNG THƯ SỐ HOTLINE:

HƯỚNG DẪN SỬ DỤNG PLESK PANEL

Tình huống 1: PPPoE với Username và Password

Giáo trình này được biên dịch theo sách hướng dẫn của Sun Light. Vì là hướng dẫn kỹ thuật, trong này những thuật ngữ kỹ thuật bằng tiếng Anh tôi chỉ

Entity Framework (EF)

Khoa KH & KTMT Bộ môn Kỹ Thuật Máy Tính

Nhấn nút New để tạo 1 biến mới Trang 17

Cụ thể những công việc mà AndroidManifest.xml thực hiện: - Đặt tên cho Java package của ứng dụng.

TÀI LIỆU THỰC HÀNH MÔN CƠ SỞ DỮ LIỆU NÂNG CAO

Tính kế thừa-2. Bởi: Thanh Hiền Vũ. Định nghĩa lại các thành viên lớp cơ sở trong một lớp dẫn xuất:

HƯỚNG DẪN CÀI ĐẶT PHẦN MỀM DIỆT VIRUS AVIRA

HƯỚNG DẪN SỬ DỤNG ĐẦU GHI H.264 DVR VISION VS (4CH - 8CH - 16CH)

BÀI 1: VBA LÀ GÌ? TẠO MACRO, ỨNG DỤNG CÁC HÀM TỰ TẠO (UDF), CÀI ĐẶT ADD-INS VBA là gì?

ĐỌC, GHI XML VỚI C# TRONG ADO.NET --- SỬ DỤNG VISUAL STUDIO

Tài liệu hướng dẫn: Stored Procedure

Nội dung chính của chương. Các công nghệ đĩa cứng Cấu tạo vật lý của đĩa cứng Cấu tạo logic của đĩa cứng Cài đặt đĩa cứng như thế nào?

Chương 6. Transport Layer. Tài liệu : Forouzan, Data Communication and Networking

Bài Thực hành Asp.Net - Buổi 1 - Trang: 1

HƯỚNG DẪN CÁCH SỬ DỤNG WINDOWS MOVIE MAKER

SIMULATE AND CONTROL ROBOT

SIEMENS INDUSTRIAL NETWORKS

TỔNG QUAN VỀ.NET VÀ C#

Mô hình dữ liệu quan hệ (Relational data model)

STACK và QUEUE. Lấy STACK

Chương 7. Application Layer. Tài liệu : Forouzan, Data Communication and Networking

BẢO MẬT TRONG SQL SERVER

CẤU TRÚC DỮ LIỆU NÂNG CAO

I. Hướng Dẫn Đăng Nhập:

Đa ngôn ngữ (Internationalization) trong Servlet

Bài tập căn bản Visual Basic.Net Vòng lặp. txtn. txtketqua. btntinh. txtn. txtketqua. btntinh. Trang 1

Bộ môn MMT&TT, Khoa Công Nghệ Thông Tin và TT, ĐH Cần Thơ

Ôn tập Thiết bị mạng và truyền thông DH07TT - Lưu hành nội bộ (không sao chép dưới mọi hình thức)

Bài 13: C++11. EE3490: Kỹ thuật lập trình HK1 2017/2018 TS. Đào Trung Kiên ĐH Bách khoa Hà Nội

BÀI 6 LÀM VIỆC VỚI THÀNH PHẦN MỞ RỘNG CỦA CSS3

B5: Time to coding. Tới thư mục src/example.java và thay đổi nội dung file như sau: Mã: package at.exam;

Lab01: M V C Lưu ý: Để thực hành, các bạn phải cài Visual Studio 2013 trở lên mới hỗ trợ MVC5.

GV: Phạm Đình Sắc or

Tạo repository mới. The working tree. The staging index. Lệnh git init tạo một repository loại git. tại thư mục hiện tại: $ git init

NHẬP MÔN LẬP TRÌNH KHOA HỌC DỮ LIỆU. Bài 10: Thư viện Pandas (2)

LẬP TRÌNH WINDOWS FORM VỚI CÁC CONTROL NÂNG CAO (Các control trình bày dữ liệu dưới dạng danh sách)

Tìm hiểu Group Policy Object và các ví dụ

LÂ P TRI NH WEB ASP.NET

CHƯƠNG 2: CÁC ĐẶC ĐIỂM VỀ MÔI TRƯỜNG PHÁT TRIỂN (IDE)

HƢỚNG DẪN TRIỂN KHAI KASPERSKY - MOBILE DEVICE MANAGEMENT

Tạo Project với MPLAB

BÀI THỰC HÀNH SỐ 1. Quản trị tập tin: 1/ Tạo các thư mục sau: Bài tập thực hành linux Linuxlab. bt1 bt11 bt111. bt121. bt12. bh1 bh11 bh111.

Exceptions. Outline 7/31/2012. Exceptions. Exception handling is an important aspect of objectoriented. Chapter 10 focuses on:

Phần 1: Hướng dẫn sử dụng PictureBox tạo Slide Show

Bài 10: Cấu trúc dữ liệu

Online Appointment System will work better with below conditions/ Hệ thống đặt hẹn online sẽ hoạt động tốt hơn với điều kiện sau đây:

Cập nhật ResultSet trong JDBC

KIẾN TRÚC MÁY TÍNH. Giảng viên: ThS. Phan Thanh Toàn. v

HƯỚNG DẪN SỬ DỤNG NHANH MINDJET MIND MANAGER

Bài tập lớn số 1. Giả lập bộ định thời

Bài 10. Cấu trúc liên nối. khác nhau được gọi là cấu trúc liên nối. nhu cầu trao đổi giữa các module.

BELGIUM ONLINE APPOINTMENT

MỤC LỤC. Giáo trình Thiết kế web Trang 1

GIẢI THUẬT ĐỊNH TUYẾN (ROUTING ALGORITHM)

HỢP ĐỒNG MUA BÁN HÀNG HÓA QUỐC TẾ GV: NGUYỄN THỊ BÍCH PHƯỢNG

TÀI LIỆU HƯỚNG DẪN SỬ DỤNG HOSTING PLESK PANEL

Các kiểu định địa chỉ họ MSC-51

NHÚNG. Vi ñiều khiển BM Kỹ Thuật ðiện Tử - ðh Bách Khoa TP.HCM 2

BÀI GIẢNG CHƯƠNG 3 GIAO TIẾP KẾT NỐI SỐ LIỆU

PHÁT TRIỂN ỨNG DỤNG WEB

Lecture 12. Trees (1/2) Nội dung bài học:

Bài 7: Các cấu trúc điều khiển

Bài thực hành số 2 QUYỀN và ROLE

2.4. GIAO THỨC MQTT Các khái niệm cơ bản MQTT được phát triển bởi IBM và Eurotech, phiên bản mới nhất là MQTT 3.1 MQTT (Giao vận tầm xa) là

Google Search Engine. 12/24/2014 Google Search Engine 1

CHAPTER 6: DANH SÁCH LIÊN KẾT (LINKED LISTS)

Môn Học: Cơ Sở Dữ Liệu 2. Chương 3 LẤY DỮ LIỆU TỪ NHIỀU NGUỒN

HƯỚNG DẪN SỬ DỤNG DỊCH VỤ CDN

Hướng Dẫn Thực Hành Tập tin & Thư mục

HƯỚNG DẪN SỬ DỤNG DỊCH VỤ CDN

CHƯƠNG 5: LẬP TRÌNH HƯỚNG ĐỐI TƯỢNG TRONG VB.NET

LAB IP SLA Bài 1. Bùi Quốc Kỳ ***

HƯỚNG DẪN QUẢN TRỊ HỆ THỐNG

Khối: Cao Đẳng nghề và Trung Cấp Năm 2009

dụng một chính sách, điều này giúp dễ dàng quản lý và cung cấp tính năng Load Balancing (cân bằng tải) phục vụ tốt hơn các yêu cầu của tổ chức.

Time Picker trong Android

Hệ điều hành Bài tập tuần 7_ Chúng ta làm quen một số lệnh thao tác với hệ thống file trong Linux :

METAPOST. 1.1 Cấu trúc file Metapost. 1.2 Cấu trúc trong Preamble. beginfig(...) endfig;... extra_beginfig(...) extra_endfig... begingraph(...

B3: Bên khung Package Explore bên trái đi tới thư mục res, bạn sẽ thấy có 3 thư mục con:

Qu n ả tr h ố g t p ậ tin

Khoa Công Nghệ Thông Tin Trường Đại Học Cần Thơ. Những hỗ trợ tiên tiến khác của SQL. Đỗ Thanh Nghị

3 cách Backup Profile trong Windows 7

LINQ TO SQL & ASP.NET

Phần 2. SỬ DỤNG POWERPOINT ĐỂ CHUẨN BỊ NỘI DUNG TRÌNH BÀY

BÀI LAB ĐỔI TÊN DOMAIN

Dọn "rác" Windows 7 vào dịp cuối năm

HTML DOM - Forms. MSc. nguyenhominhduc

Transcription:

Bài 9: Kế thừa (Inheritance) 1

Khái niệm Để quản lý nhân sự của công ty, ta có thể định nghĩa các lớp tương ứng với các vị trí làm việc của công ty: class Worker { private: string name; float salary; int level; string getname() {} void pay() {} void dowork() {} class Manager { private: string name; float salary; int dept; string getname() {} void pay() {} void dowork() {} class Director { private: string name; float salary; string getname() {} void pay() {} void dowork() {} Cả 3 lớp trên đều có những biến và hàm giống hệt nhau về nội dung tạo ra một lớp Employee chứa các thông tin chung đó để sử dụng lại Sử dụng lại code Giảm số code cần viết Dễ bảo trì, sửa đổi về sau Rõ ràng hơn về mặt logic trong thiết kế chương trình 2

Khái niệm (tiếp) Lớp mẹ (hay lớp cơ sở) Employee Các lớp con (hay lớp dẫn xuất) Worker Manager Director Hai hướng thừa kế: Cụ thể hoá: lớp con là một trường hợp riêng của lớp mẹ (như ví dụ trên) Tổng quát hoá: mở rộng lớp mẹ (vd: Point2D thêm biến z để thành Point3D) Kế thừa cho phép các lớp con sử dụng các biến và phương thức của lớp mẹ như của nó, trừ các biến và phương thức private Kế thừa với public và private: các thành phần public của lớp mẹ vẫn là public trong lớp con private: toàn bộ các thành phần của lớp mẹ trở thành private của lớp con 3

Kế thừa public class Employee { private: string name; float salary; string getname() {} void pay() {} class Worker : public Employee { private: int level; void dowork() {} void show() { cout << getname() << salary; // lỗi } Worker w; w.getname(); w.dowork(); w.pay(); w.salary = 10; // lỗi w.show(); Employee e = w; // OK Worker w2 = e; // lỗi Worker w3 = (Worker)e; // lỗi Các thành phần public của lớp mẹ vẫn là public trong lớp con Lớp con chuyển kiểu được thành lớp mẹ, nhưng ngược lại không được 4

Kế thừa private class LinkedList { private: void inserttail(int x) { } void inserthead(int x) { } void deletehead() { } void deletetail() { } int gethead() { } int gettail() { } class Stack : private LinkedList { void push(int x) { inserthead(x); } int pop() { int x = gethead(); deletehead(); return x; } Stack s; s.push(10); s.push(20); s.pop(); s.inserttail(30); // lỗi s.gettail(); // lỗi Tất cả các thành phần của lớp mẹ đều trở thành private của lớp con 5

Thành phần protected Ngoài public và private, còn có các thành phần protected: có thể được sử dụng bởi các phương thức trong lớp dẫn xuất từ nó, nhưng không sử dụng được từ ngoài các lớp đó class Employee { protected: string name; float rate; int hours; int getsalary() { return rate*hours; } void setname(const char* s) { name = s; } string getname() { return name; } void pay() { } 6 class Worker: public Employee { void dowork() { } void print() { cout << "Ten: " << name << "Luong: " << getsalary(); } Worker w; w.dowork(); w.pay(); w.print(); w.name = "NV Tung"; // lỗi cout << w.getsalary(); // lỗi

Tổng kết các kiểu kế thừa Kiểu kế thừa private protected public Phạm vi private private private private protected private protected protected public private protected public Cột: các kiểu kế thừa Hàng: phạm vi các biến/phương thức thành phần trong lớp mẹ Kết quả: phạm vi các biến/phương thức trong lớp dẫn xuất 7

Constructor và destructor trong kế thừa Constructor và destructor không được các lớp con thừa kế Mỗi constructor của lớp dẫn xuất phải gọi một constructor của lớp mẹ, nếu không sẽ được ngầm hiểu là gọi constructor mặc định class Pet { Pet() {} Pet(string name) {} class Dog: public Pet { Dog() {} // Pet() Dog(string name): Pet(name) {} class Bird { Bird(bool canfly) {} class Eagle: public Bird { // sai: Eagle() {} Eagle(): Bird(true) {} Destructor của các lớp sẽ được gọi tự động theo thứ tự ngược từ lớp dẫn xuất tới lớp cơ sở ~Dog() ~Pet() ~Eagle() ~Bird() 8

Gọi cons của lớp mẹ trong cons của lớp con 9 Không thể gọi cons của lớp mẹ trong cons của lớp con như hàm, mà phải gọi ở danh sách khởi tạo class Point3D: private Point2D { protected: double z; Point3D(): Point2D(0., 0.), z(0.) // đúng { } Point3D(double x, double y, double z) { } // gọi cons mặc định Point2D() Point2D(x, y); // sai: tạo đối tượng Point2D tạm this->z = z;

Phương thức ảo (virtual method) bắt buộc Là phương thức được khai báo ở lớp mẹ, nhưng có thể được định nghĩa lại (thay thế) ở các lớp dẫn xuất class Shape { virtual void draw() { cout<<"shape::draw\n"; } Kết quả chạy: void erase() Circle::erase { cout<<"shape::erase\n"; } Circle::draw void redraw() Shape::erase { erase(); draw(); } Shape::draw Shape::erase có thể bỏ Circle::draw class Circle: public Shape { Shape::erase Circle::draw virtual void draw() Shape::erase { cout<<"circle::draw\n"; Circle::draw } void erase() Shape::erase { cout<<"circle::erase\n"; Shape::draw } } Shape::erase Circle::draw 10 Shape::erase Circle::draw void main() { Circle c; Shape s1 = c; Shape& s2 = c; Shape* s3 = &c; c.erase(); c.draw(); s1.erase(); s1.draw(); s2.erase(); s2.draw(); s3->erase(); s3->draw(); c.redraw(); s1.redraw(); s2.redraw(); s3->redraw();

Lớp trừu tượng (abstract class) Phương thức ảo thuần tuý (pure virtual method): là phương thức được khai báo nhưng chưa được định nghĩa cần được định nghĩa trong các lớp dẫn xuất Lớp trừu tượng là lớp có phương thức ảo thuần tuý Không thể tạo được đối tượng từ lớp trừu tượng class Shape { virtual void draw() = 0; virtual void erase() = 0; virtual void area() = 0; void redraw() { } class Circle: public Shape { virtual void draw() { } virtual void erase() { } virtual void area() { } Shape p; // lỗi Circle c; Shape p2 = c; // lỗi Shape& p3 = c; // OK Shape* p4 = &c; // OK void func(shape s) {} // lỗi void func(shape& s) {} // OK void func(shape* s) {} // OK 11

Tính đa hình (polymorphism) Thừa kế và định nghĩa các hàm ảo giúp quản lý đối tượng dễ dàng hơn: có thể gọi đúng phương thức mà không cần quan tâm tới lớp thực sự của nó là gì (trong C phải dùng switch hoặc con trỏ hàm) class Pet { virtual void say() = 0; class Cat: public Pet { virtual void say() { cout << "miao\n"; } Pet* p[3] = { new Dog(), new Cat(), new Cat() for (int i=0; i<3; i++) p[i]->say(); // // Thế này không được: // Pet p2[2] = { Dog(), Cat() // class Dog: public Pet { virtual void say() { cout << "gruh\n"; } Kết quả chạy: gruh miao miao 12

Destructor ảo class ClassA { ClassA() { } ~ClassA() { } class ClassB: public ClassA { ClassB() { } ~ClassB() { } ClassB* b = new ClassB; ClassA* a = (ClassA*)new ClassB; delete b; // ~ClassB, ~ClassA delete a; // ~ClassA class ClassA { ClassA() { } virtual ~ClassA() { } class ClassB: public ClassA { ClassB() { } virtual ~ClassB() { } ClassB* b = new ClassB; ClassA* a = (ClassA*)new ClassB; delete b; // ~ClassB, ~ClassA delete a; // ~ClassB, ~ClassA Nên luôn khai báo destructor ảo nếu không có gì đặc biệt 13

Biểu diễn trong bộ nhớ #pragma pack(1) class V2 { double x, y; static int i; void f2(); virtual void fv2(); class V3: public V2 { double z; void f3(); virtual void fv2(); virtual void fv3(); V3 v3; V2& v2 = v3; 14 printf("%d %d\n", &v2, sizeof(v2)); printf("%d %d\n", &v3, sizeof(v3)); printf("%d %d %d\n", &v3.x, &v3.y, &v3.z); Kết quả chạy: 1245000 20 1245000 28 1245004 1245012 1245020 Thành phần Kích thước vtable 4 x 8 y 8 z 8 Dữ liệu static không nằm trong đối tượng Nếu lớp có phương thức ảo, thêm một con trỏ (vtable) tới một bảng các phương thức ảo phương thức ảo tương tự như con trỏ hàm Dữ liệu của lớp con sẽ được nối tiếp vào sau dữ liệu của lớp mẹ Chú ý việc chỉnh biên dữ liệu (data alignment) V2 V3 vtable fv2() fv3()

Đa kế thừa (kế thừa nhiều lớp) 15 C++ cho phép một lớp có thể kế thừa từ nhiều lớp khác nhau class Camera { void takepicture(); class FMDevice { void turnon(); void turnoff(); void setfreq(float f); class Phone { void call(string num); class CellPhone: public Camera, protected FMDevice, public Phone { void turnfmon(); void turnfmoff(); void setfmfreq(float f); CellPhone p; p.takepicture(); p.turnon(); // lỗi p.turnfmon(); p.call("0912345678");

Thành phần trùng tên class Legged { void move() { } class Winged { void move() { } class Pigeon: public Legged, public Winged { Pigeon p1; p1.move(); // lỗi p1.legged::move(); // Legged p1.winged::move(); // Winged ((Legged&)p1).move(); // Legged ((Winged&)p1).move(); // Winged class Penguin: public Legged, public Winged { void move() { Legged::move(); } Penguin p2; p2.move(); // Penguin ((Legged&)p2).move(); // Legged ((Winged&)p2).move(); // Winged Đa kế thừa có thể khiến chương trình trở nên rất phức tạp và khó kiểm soát các biến/phương thức thành phần chỉ nên sử dụng khi thực sự cần thiết 16

Biểu diễn đa kế thừa trong bộ nhớ class B1 {} class B2 {} class D: public B1, public B2 {} class B1 double a, b; virtual void fb1(); class B2 int c; virtual void fb2(); D d; B1& b1 = d; B2& b2 = d; printf("%d %d\n", &d, sizeof(d)); printf("%d %d\n", &b1, sizeof(b1)); printf("%d %d\n", &b2, sizeof(b2)); class D float d; virtual void fb1(); virtual void fb2(); virtual void fd(); Kết quả chạy: 1244996 32 1244996 20 1245016 8 17 Các thành phần của các lớp cơ sở nằm nối tiếp nhau trong bộ nhớ Lớp kế thừa ảo: tự tìm hiểu thêm vtable fb1() fd() vtable fb2() Thành phần Kích thước vtable 4 a 8 b 8 vtable 4 c 4 d 4 B1 B2 D

Bài tập 1. Định nghĩa kiểu struct Shape trong C rồi viết các hàm draw(), area() tuỳ theo dạng hình: tròn, vuông, chữ nhật. Dùng hai cách làm: dùng switch, con trỏ hàm. So sánh với cách làm trong C++. 2. Với điều kiện nào thì có thể lưu một đối tượng ra file rồi đọc lại trong lần chạy sau như dưới đây? Giải thích và chạy thử. lần chạy trước: fwrite((void*)&obj, 1, sizeof(obj), file); lần chạy sau: fread((void*)&obj, 1, sizeof(obj), file); 3. Viết các lớp Shape (trừu tượng) và Circle, Square, Rectangle, Ellipse, Sphere. Hãy thiết kế việc kế thừa sao cho hợp lý. 4. Hoàn tất các lớp Employee, Worker, Manager, Director và viết một chương trình thử. 5. Mở rộng và sửa bài tập trên: Thêm lớp Company chứa toàn bộ các nhân viên Thêm quan hệ về công việc giữa các nhân viên. VD: mỗi Worker có 1 Manager, 6. Viết các lớp B1, B2 và D trong phần đa kế thừa rồi kiểm tra kích thước các kiểu và địa chỉ các thành phần so với địa chỉ của đối tượng. 18