1 / 107

MÔN LẬP TRÌNH H ƯỚNG ĐỐI TƯỢNG

MÔN LẬP TRÌNH H ƯỚNG ĐỐI TƯỢNG. Đối tượng : SV đại học chính quy ngành CNTT. Tài liệu tham khảo : Tập slide bài giảng & thực hành của môn học này. The C++ Programming Language (special 3rd edition), Bjarne Stroustrup, 2000. 3 CD MSDN trong Microsoft Visual Studio.

claus
Download Presentation

MÔN LẬP TRÌNH H ƯỚNG ĐỐI TƯỢNG

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. MÔN LẬP TRÌNH HƯỚNG ĐỐI TƯỢNG Đối tượng : SV đại học chính quy ngành CNTT • Tài liệu tham khảo : • Tập slide bài giảng & thực hành của môn học này. • The C++ Programming Language (special 3rd edition), Bjarne Stroustrup, 2000. • 3 CD MSDN trong Microsoft Visual Studio. • Online-Help của môi trường JBuilder

  2. MÔN LẬP TRÌNH HƯỚNG ĐỐI TƯỢNG • Nội dung chính gồm 10 chương : • Ôn lại các tính chất của lập trình cấu trúc. • Các khái niệm chính của lập trình OOP. • Cơ chế dịch mã OOP sang mã máy. • Tổng quát về mức độ hỗ trợ OOP của VC++ & Java. • Đặc tả class & các tính chất cơ bản của đối tượng trong VC++. • Đặc tả class & các tính chất cơ bản của đối tượng trong Java. • Chi tiết về gọi hàm, gởi thông điệp & đa xạ của VC++. • Chi tiết về gọi hàm, gởi thông điệp & đa xạ của Java. • Chi tiết về thường trú, serialization, COM, Generalization & Template của VC++. • Chi tiết về thường trú, serialization, Generalization của Java.

  3. MÔN LẬP TRÌNH HƯỚNG ĐỐI TƯỢNG Chương 1 ÔN LẠI CÁC TÍNH CHẤT CỦA LẬP TRÌNH CẤU TRÚC Chương 1: Ôn lại các tính chất của lập trình cấu trúc

  4. Phương pháp phân tích từ-trên-xuống Mỗi sự vật trong môi trường xung quanh ta đều được cấu thành từ nhiều phần tử nhỏ hơn, mỗi phần tử nhỏ lại được cấu thành từ nhiều phần tử nhỏ hơn nữa. Thí dụ, con người gồm đầu, mình, tứ chi. Tứ chi gồm 2 tay và 2 chân... Mỗi công việc cần giải quyết bằng máy tính cũng được cấu thành từ nhiều công việc nhỏ hơn, mỗi công việc nhỏ hơn lại được cấu thành từ nhiều công việc nhỏ hơn nữa... Phương pháp phân tích từ-trên-xuống (top-down analysis) là phương pháp thường sử dụng để phân tích công việc, nội dung của phương pháp này là cố gắng xác định xem công việc cần giải quyết được cấu thành từ những công việc nhỏ nào, mỗi công việc nhỏ được cấu thành từ các công việc nhỏ hơn nào, cứ như vậy cho đến khi những công việc xác định được là những công việc thật đơn giản, có thể thực hiện dễ dàng. Thí dụ việc học lấy bằng kỹ sư CNTT khoa CNTT ĐHBK TP.HCM có thể bao gồm 9 công việc nhỏ hơn là học từng học kỳ từ 1 tới 9, học học kỳ i là học n môn học của học kỳ đó, học 1 môn học là học m chương của môn đó,... Hình vẽ của slide kế cho thấy trực quan của phương pháp phân tích top-down. Chương 1: Ôn lại các tính chất của lập trình cấu trúc

  5. Công việc cần giải quyết (A) chia thành nhiều công việc nhỏ hơn, đơn giản để giải quyết hơn. ... Công việc Ann Công việc An2 Công việc A12 Công việc A11 Công việc A1n Công việc A2 Công việc A1 Công việc An1 Công việc An Các công việc đủ nhỏ để được miêu tả bằng 1 lệnh hay 1 lời gọi hàm/thủ tục đã có. ... ... ... ... Phương pháp phân tích từ-trên-xuống (tt) Chương 1: Ôn lại các tính chất của lập trình cấu trúc

  6. Tầm vực truy xuất biến • Tầm vực của một biến là tập các lệnh được phép truy xuất biến đó. • C và C++ cho phép 3 cấp độ tầm vực sau : • cục bộ trong function : bất kỳ lệnh nào trong function đều có thể truy xuất được biến cục bộ trong function đó. void Command1_Click() { char strGreeting[256]; // Khai báo cục bộ ... } • cục bộ trong module : bất kỳ lệnh nào trong module đều có thể truy xuất được biến cục bộ trong module đó. static char strAddr[256]; // biến cục bộ trong module char strName[256]; // biến toàn cục • toàn cục : bất kỳ lệnh nào trong chương trình cũng có thể truy xuất được biến toàn cục. • Trong một ngữ cảnh (cùng 1 function, cùng 1 module, hay cấp toàn cục), không thể dùng hai biến cùng tên (C phân biệt chữ HOA và chữ thường). Chương 1: Ôn lại các tính chất của lập trình cấu trúc

  7. Cấu trúc 1 chương trình hướng cấu trúc Chương trình = cấu trúc dữ liệu + giải thuật module (package) global data local data of module entry 'start' local data of function Chương 1: Ôn lại các tính chất của lập trình cấu trúc

  8. Cấu trúc 1 chương trình hướng cấu trúc • Thành phần “giải thuật” bao gồm code được viết trong các module. Trong từng module, code được gom nhóm thành những hàm chức năng, mỗi hàm được nhận dạng và truy xuất thông qua tên hàm. • Thành phần “dữ liệu” bao gồm các biến dữ liệu được định nghĩa trong các module. Trong từng module, về mặt tầm vực truy xuất, các biến có thể được định nghĩa 1 trong 2 cấp tầm vực : • Public : bất kỳ lệnh nào của chương trình đều có thể truy xuất được. • Private : chỉ có các lệnh trong module hiện hành mới có thể truy xuất. • Ngoài ra trong từng hàm chức năng, người ta có thể định nghĩa các biến cục bộ, các biến này chỉ được truy xuất cục bộ bởi các lệnh trong hàm tương ứng. Ngoại lệ, trong 1 số ngôn ngữ như C, người ta cho phép định nghĩa biến trong lệnh thực thi (block – compose), biến này chỉ được truy xuất cục bộ bởi các lệnh trong thân của lệnh block tương ứng.  điểm yếu nhất trong ngôn ngữ hướng cấu trúc là cho phép định nghĩa biến toàn cục, nếu biến này bị lỗi, ta rất khó xác định nguyên nhân gây lỗi. Việc mang 1 hàm hay 1 module của ứng dụng này sang ứng dụng khác cũng sẽ khó khăn vì thường gây ra hiệu ứng “dây chuyền”. Chương 1: Ôn lại các tính chất của lập trình cấu trúc

  9. Cấu trúc 1 chương trình hướng cấu trúc • Xét Turbo Pascal, 1 ứng dụng gồm 1 module chương trình và nhiều module dịch vụ được gọi là Unit. Để sử dụng các thành phần trong 1 module nào đó, ta phải dùng lệnh Use. • Xét C, 1 ứng dụng gồm nhiều module ngang hàng, mỗi module là 1 file gồm nhiều hàm chức năng. Điểm nhập ứng dụng là hàm main(). Module C cũng có thể là file thư viện liên kết tĩnh (*.lib) hay động (*.dll). Để sử dụng các thành phần trong 1 module nào đó, ta phải dùng lệnh #include. Chương 1: Ôn lại các tính chất của lập trình cấu trúc

  10. Mối quan hệ client/server giữa các module //đặc tả interface của module B : server extern int B_intA; typedef struct {...} B_Type1; #define B_MAXLEN 1024 int B_func1(char c, char* d); //đặc tả interface của module A : client #include B.h extern int A_intA; typedef struct {...} A_Type1; #define A_PI 3.14159 int A_func1(int a, double b); #include B.h //hiện thực của module B int B_intA; static int B_intB; int B_func1(int a, double b) { ... B_func2(a); ... } static void B_func2(int a) { } #include A.h //hiện thực của module A int A_intA; static int A_intB; int A_func1(int a, double b) { B_Type1 var; ... B_intA = B_MAXLEN; A_func2(a); B_func1(a,b); } static void A_func2(int a) { } Chương 1: Ôn lại các tính chất của lập trình cấu trúc

  11. Hai module sử dụng tài nguyên của nhau //đặc tả interface của module B #define _BH #ifndef _AH #include A.h #endif extern int B_intA; typedef struct {...} B_Type1; #define B_PI 3.14159 int B_func1(char c, char* d); //đặc tả interface của module A #define _AH #ifndef _BH #include B.h #endif extern int A_intA; typedef struct {...} A_Type1; #define A_PI 3.14159 int A_func1(int a, double b); #include B.h //hiện thực của module B int B_intA; static int A_intB; int B_func1(int a, double b) { ... B_func2(a); ... } static void B_func2(int a) { } #include A.h //hiện thực của module A int A_intA; static int A_intB; int A_func1(int a, double b) { ... A_func2(a); ... } static void A_func2(int a) { } Chương 1: Ôn lại các tính chất của lập trình cấu trúc

  12. MÔN LẬP TRÌNH HƯỚNG ĐỐI TƯỢNG Chương 2 CÁC KHÁI NIỆM CHÍNH CỦA LẬP TRÌNH HƯỚNG ĐỐI TƯỢNG Chương 2 : Các khái niệm chính của lập trình hướng đối tượng

  13. Nội dung 2.1 Cấu trúc của 1 ứng dụng hướng đối tượng 2.2 Đối tượng, thuộc tính, tác vụ. 2.3 Abstract type và class. 2.4 Tính bao đóng. 2.5 Tính thừa kế & cơ chế 'override'. 2.6 Tính bao gộp. 2.7 Thông điệp, tính đa xạ và kiểm tra kiểu. 2.8 Tính tổng quát hóa. 2.9 Tính thường trú. Chương 2 : Các khái niệm chính của lập trình hướng đối tượng

  14. Cấu trúc chương trình OOP Chương trình = tập các đối tượng tương tác nhau Đối tượng (object) local data of object entry local data of operation Chương 2 : Các khái niệm chính của lập trình hướng đối tượng

  15. Cấu trúc chương trình OOP • Cấu trúc chương trình hướng đối tượng rất thuần nhất, chỉ chứa 1 loại thành phần : đối tượng. • Các đối tượng có tính độc lập rất cao  quản lý, kiểm soát chương trình rất dễ (cho dù chương trình có thể rất lớn)  dễ nâng cấp, bảo trì. • Không thể tạo ra dữ liệu toàn cục của chương trình  điểm yếu nhất của chương trình cấu trúc không tồn tại nữa. Chương 2 : Các khái niệm chính của lập trình hướng đối tượng

  16. Đối tượng (Object) • Đối tượng là nguyên tử cấu thành ứng dụng. • Đối tượng bao gồm 2 loại thành phần : • thuộc tính (dữ liệu) : mỗi thuộc tính mang 1 giá trị nhất định tại từng thời điểm. • tác vụ (operation) : thực hiện 1 công việc nào đó. Implementation (class) Interface (abstract type) Chương 2 : Các khái niệm chính của lập trình hướng đối tượng

  17. Kiểu trừu tượng (Abstract type) • Abstract type (type) định nghĩa interface sử dụng đối tượng. Ta dùng tên nhận dạng để đặt tên cho kiểu và để nhận dạng nó. • Interface là tập hợp các 'entry' mà bên ngoài có thể giao tiếp với đối tượng. • Ta dùng signature để định nghĩa mỗi 'entry'. Signature gồm : • tên tác vụ (operation, function) • danh sách tham số hình thức, mỗi tham số được đặc tả bởi 3 thuộc tính : tên, type và chiều di chuyển (IN, OUT, INOUT). • đặc tả chức năng của tác vụ (thường ở dạng chú thích). • Ta dùng tên của abstract type (chứ không phải class) để đặc tả kiểu cho biến, thuộc tính, tham số hình thức. • User không cần quan tâm đến class (hiện thực cụ thể) của đối tượng. Chương 2 : Các khái niệm chính của lập trình hướng đối tượng

  18. Kiểu trừu tượng trong Java Java hỗ trợ kiểu trừu tượng thông qua lệnh interface, lệnh này định nghĩa abstract type của nhiều đối tượng của ứng dụng (có thể thuộc nhiều class khác nhau. public interface Sleeper { public void wakeUp(); public long ONE_SECOND = 1000; // in milliseconds public long ONE_MINUTE = 60000; // in milliseconds } public class DigitalClock extends Applet implements Sleeper {…} public class AnalogClock extends Applet implements Sleeper {…} … Sleeper object; Object = new DigitalClock(); //biến object giữ tham khảo đến 1 đối tượng DigitalClock Object = new AnalogClock(); //biến object giữ tham khảo đến 1 đối tượng AnalogClock Chương 2 : Các khái niệm chính của lập trình hướng đối tượng

  19. Class (Implementation) • Ta dùng tên nhận dạng để đặt tên cho class và để nhận dạng nó. Class định nghĩa chi tiết hiện thực đối tượng : • định nghĩa các thuộc tính dữ liệu, mỗi thuộc tính được đặc tả bởi các thông tin về nó như tên nhận dạng, kiểu dữ liệu, tầm vực truy xuất,... Kiểu của thuộc tính có thể là type cổ điển (số nguyên, thực, ký tự, chuỗi ký tự,...) hay 'abstract type', trong trường hợp sau thuộc tính sẽ là tham khảo đến đối tượng khác. Trạng thái của đối tượng là tập giá trị tại thời điểm tương ứng của tất cả thuộc tính của đối tượng. Trong thời gian tồn tại và hoạt động, trạng tái của đối tượng sẽ thay đổi. • 'coding' các tác vụ (miêu tả giải thuật chi tiết về hoạt động của tác vụ) và các 'internal function'. • Định nghĩa các tác vụ tạo (create) và xóa (delete) đối tượng. • Định nghĩa các tác vụ 'constructor' và 'destructor'. • User không cần quan tâm đến class của đối tượng. Chương 2 : Các khái niệm chính của lập trình hướng đối tượng

  20. Ví dụ về định nghĩa class trongVC++ class CMiniChatClientDlg : public CDialog{ public: CMiniChatClientDlg(CWnd* pParent = NULL); // standard constructor protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam); virtual BOOL OnInitDialog(); afx_msg void OnPaint(); afx_msg void OnConnect(); HICON m_hIcon; private : SOCKET sock; u_short portno; // Which tcp port are we going to use? }; Chương 2 : Các khái niệm chính của lập trình hướng đối tượng

  21. Tính bao đóng (encapsulation) • Bao đóng : che dấu mọi chi tiết hiện thực của đối tượng, không cho bên ngoài thấy và truy xuất tạo độ độc lập cao giữa các đối tượng (hay tính kết dính - cohesion giữa các đối tượng rất thấp). • che dấu các thuộc tính dữ liệu : nếu cần cho phép bên ngoài truy xuất 1 thuộc tính, ta tạo 2 tác vụ get/set tương ứng để giám sát và kiểm soát việc truy xuất (thuộc tính này vẫn được che giấu). • che dấu chi tiết hiện thực các tác vụ. • che dấu các internal function và sự hiện thực của chúng. • Java, VC++ cung cấp các từ khóa private, protected, public để xác định tầm vực truy xuất từng thành phần của class. Chương 2 : Các khái niệm chính của lập trình hướng đối tượng

  22. Tính thừa kế (inheritance) • Tính thừa kế cho phép giảm nhẹ công sức định nghĩa type/class : ta có thểđịnh nghĩa các type/class không phải từđầu mà bằng cách kế thừa type/class có sẵn, ta chỉđịnh nghĩa thêm các chi tiết mới mà thôi (thường khá ít). • Đa thừa kế hay đơn thừa kế. • Thừa kế tạo ra mối quan hệ supertype/subtype và superclass/subclass. • Có thể override các method của class cha, kết quả override chỉ tác dụng trên đối tượng của class con. • Đối tượng của class con có thể đóng vai trò của đối tượng class cha nhưng ngược lại thường không được. • VC++ cho phép hạn chế tầm vực truy xuất các thành phần của class cha : class C : protected A, private B {…} Chương 2 : Các khái niệm chính của lập trình hướng đối tượng

  23. Ví dụ về thừa kế và override – VC++ class Geometry { // abstract base class public: Geometry( ); virtualvoid Draw( Window *pWnd ) = 0; // abstract operation protected: int xPos, yPos; COLORREF color; }; class Group : public Geometry { public: Group( ); ~Group( ); virtualvoid Draw( Window *pWnd ); // override private: Geometry **ppGeo; // pointer container int geoCount; }; Chương 2 : Các khái niệm chính của lập trình hướng đối tượng

  24. Tính bao gộp (aggregation) • 1 đối tượng có thể chứa nhiều đối tượng khác  tạo nên mối quan hệ bao gộp 1 cách đệ quy giữa các đối tượng. • Có 2 góc nhìn về tính báo gộp : ngữ nghĩa & hiện thực. Góc nhìn ngữ nghĩa Góc nhìn hiện thực O2 O2 O1 O1 O3 O3 Chương 2 : Các khái niệm chính của lập trình hướng đối tượng

  25. Ví dụ về bao gộp - VC++ class Geometry { // abstract base class public: Geometry( ); ~Geometry( ); virtualvoid Draw( Window *pWnd ) = 0; // abstract operation protected: int xPos, yPos; double xScale, yScale; COLORREF color; }; class Group : public Geometry { public: Group( ); ~Group( ); virtualvoid Draw( Window *pWnd ); // override private: Geometry **ppGeo; // =Geometry* ppGeo[n]; int geoCount; }; Chương 2 : Các khái niệm chính của lập trình hướng đối tượng

  26. Thông điệp (Message) • Thông điệp là 1 phép gọi tác vụđến 1 đối tượng từ 1 tham khảo. • Thông điệp bao gồm 3 phần : • tham khảođến đối tượng đích. • Tên tác vụ muốn gọi. • danh sách tham số thực cần truyền theo (hay nhận về từ) tác vụ. • ví dụ : aCircle.SetRadius (3); aCircle.Draw (pWnd); • Thông điệp là phương tiện giao tiếp (hay tương tác) duy nhất giữa các đối tượng. Chương 2 : Các khái niệm chính của lập trình hướng đối tượng

  27. Tính đa xạ (Polymorphism) • Cùng 1 lệnh gởi thông điệp đến đối tượng thông qua cùng 1 tham khảo nhưng ở vị trí/thời điểm khác nhau có thể kích hoạt việc thực thi tác vụ khác nhau của các đối tượng khác nhau. T1 p1; // C1 và C2 là 2 class Java hiện thực T1 ... p1 = New C1; // tạo đối tượng C1, gán tham khảo vào biến p1 p1.meth1(...); // gởi thông điệp nhờ tác vụ meth1 thực thi ... p1 = New C2; // tạo đối tượng C2, gán tham khảo vào biến p1 p1.meth1(...); // gởi thông điệp nhờ tác vụ meth1 thực thi Lệnh gởi thông điệp p1.meth1(...);ở 2 vị trí khác nhau kích hoạt 2 tác vụ khác nhau của 2 class khác nhau. Chương 2 : Các khái niệm chính của lập trình hướng đối tượng

  28. Kiểm tra kiểu (type check) • Chặt và dùng mối quan hệ 'conformity' (tương thích tổng quát). Type A tương thích với type B  A chứa mọi tác vụ của B và ứng với từng tác vụ của type B : • Tồn tại 1 tác vụ cùng tên trong A. • danh sách tham số của 2 tác vụ tương ứng phải bằng nhau về số lượng tham số. • kiểu đối số OUT hay giá trị return của tác vụ trong A phải tương thích với kiểu của đối số tương ứng trong B. • kiểu đối số IN của tác vụ trong B phải tương thích với kiểu của đối số tương ứng trong A. • kiểu đối số INOUT phải trùng với kiểu của đối số tương ứng trong B. • quan hệ so trùng hay quan hệ con/cha (sub/super) làtrường hợp đặc biệt của quan hệ tương thích tổng quát. Chương 2 : Các khái niệm chính của lập trình hướng đối tượng

  29. Tính tổng quát hóa (Generalization) • Có 2 ngữ nghĩa khác nhau của tính tổng quát hóa : • class tổng quát hóa cho phép sản sinh tự động các class bình thường, các class bình thường tự nó chỉ có thể tạo ra đối tượng. Thường dùng ngữ nghĩa này trong giai đoạn lập trình. • ngược với tính thừa kế : supertype/superclass là type/class tổng quát hóa của các con của nó. Thường dùng ngữ nghĩa này trong giai đoạn phân tích/thiết kế phần mềm. Chương 2 : Các khái niệm chính của lập trình hướng đối tượng

  30. Tính thường trú (persistence) • Thời gian sống của 1 đối tượng độc lập với thời gian sống của phần tử (ứng dụng, đối tượng khác) tạo ra nó. • Đối tượng phải tồn tại khi còn ít nhất 1 tham khảo đến nó trong hệ thống. • Đối tượng phải bị xóa khi không còn tham khảo nào đến nó, vì tại thời điểm này đối tượng là rác. Việc xác định chính xác 1 đối tượng có phải là rác hay không là 1 việc phức tạp, code ứng dụng không được phép thực hiện, đây là công việc của hệ thống thông qua module 'garbage collection'. • thường trú không phải là vĩnh hằng. Mức độ có thể là 1 session của máy ảo (JVM) hay lâu dài (thông qua đĩa cứng, CDROM). Chương 2 : Các khái niệm chính của lập trình hướng đối tượng

  31. Tổng kết • Mô hình hướng đối tượng quan niệm thế giới (hay chương trình) bao gồm các đối tượng độc lập sống chung và tương tác lẫn nhau. • Các đặc điểm chính của mô hình hướng đối tượng : • Bao đóng : mỗi đối tượng bao gồm 1 số dữ liệu và tác vụ. Các tác vụ thiết lập nên hành vi của đối tượng. Các đối tượng cùng loại được đặc tả bằng 1 class. • Các đối tượng độc lập và tương tác lẫn nhau bằng cách gởi thông điệp. • Giữa các class/đối tượng có thể tồn tại quan hệ bao gộp, thừa kế, tổng quát hóa. • Tính đa xạ : kết quả của sự kiểm tra kiểu chặt dựa vào mối quan hệ 'conformity'. • Tính thường trú : mỗi đối tượng tồn tại khi còn ít nhất 1 tham khảo đến nó. Chương 2 : Các khái niệm chính của lập trình hướng đối tượng

  32. MÔN LẬP TRÌNH HƯỚNG ĐỐI TƯỢNG Chương 3 CƠ CHẾ DỊCH MÃ HƯỚNG ĐỐI TƯỢNG SANG MÃ MÁY Chương 3: Cơ chế dịch mã OOP sang mã máy

  33. Tổng quát về vấn đề dịch OOP • Chương trình là tập các đối tượng sống độc lập và tương tác lẫn nhau khi cần thiết. • Các đối tượng thuộc 1 số loại nhất định (n) • Mỗi loại đối tượng được miêu tả bởi 1 type & 1 class • Mã nguồn chương trình là tập n định nghĩa type & class • Dịch chương trình OOP là qui trình lặp dịch n type & n class. • Ta sẽ miêu tả qui trình dịch 1 type và 1 class trong chương này. Chương 3: Cơ chế dịch mã OOP sang mã máy

  34. Dịch 1 abstract type • Abstract type chỉ chứa thông tin trừu tượng (interface), không miêu tả sự hiện thực  Kết quả việc dịch 1 type chỉ dừng lại ở việc xây dựng cây ngữ nghĩa của type tương ứng để phục vụ việc kiểm tra kiểu của chương trình dịch, chứ không tạo code mã máy. • Chỉ cần 3 bước : duyệt từ vựng, phân tích cú pháp và phân tích ngữ nghĩa. • Nên dùng công cụ hỗ trợ như LEX, YACC cho 2 bước duyệt từ vựng & phân tích cú pháp. Chương 3: Cơ chế dịch mã OOP sang mã máy

  35. Dịch 1 class • Dịch class là công việc chính của chương trình dịch hướng đối tượng. • Gồm 2 công việc chính : dịch thuộc tính dữ liệu và dịch các method (hay các internal function). • Cần đầy đủ các bước : duyệt từ vựng, phân tích cú pháp, phân tích ngữ nghĩa và tạo mã. • Nên dùng công cụ hỗ trợ như LEX, YACC cho 2 bước duyệt từ vựng & phân tích cú pháp. Chương 3: Cơ chế dịch mã OOP sang mã máy

  36. Dịch thuộc tính dữ liệu typedef struct { // import các field từ cấu trúc // được sinh ra từ C0 // các field tương ứng với C1 double C1_d; int C1_i; ... // các field dữ liệu điều khiển // tự tạo bởi chương trình dịch void (*pvfaddr)() ; } C1; • class  cấu trúc record class C1 : C0 { double d; int i ; ... public : int proc4(int i); void proc5 (double d); ... }; Chương 3: Cơ chế dịch mã OOP sang mã máy

  37. Dịch thuộc tính dữ liệu (tt) • mỗi class  1 record dữ liệu cổ điển. • tên class  tên record. • copy các field dữ liệu của cấu trúc sinh ra từ việc dịch class cha. • Chuyển từng thuộc tính của class thành từng field của record, “tuyệt đối hóa” tên của thuộc tính để tránh nhặp nhằng. • thêm các field dữ liệu điều khiển phục vụ cho run-time : thí dụ bảng địa chỉ các tác vụ của đối tượng (pvftbl). Chương 3: Cơ chế dịch mã OOP sang mã máy

  38. Dịch thuộc tính dữ liệu (tt) • cấu trúc record được dịch ra mã máy thành 1 vùng nhớ liên tục có độ dài bằng đội dài của record. - khai báo biến C1 o1; C1_o1 db dup (sizeof(C1)) • truy xuất 1 thuộc tính dữ liệu trở thành việc truy xuất ô nhớ dùng cách định địa chỉ chỉ số : - o1.i = 5; mov bx, C1_o1 mov [bx+8], 5 Chương 3: Cơ chế dịch mã OOP sang mã máy

  39. Tạo bảng địa chỉ các tác vụ pvftbl fname faddr class C1 : C0 { double d; int i ; ... public : void proc2(); //override int proc4(int i, double k); void proc5 (double d); ... }; 0 "proc1" C0_proc1 1 "proc2" C1_proc2 2 "proc3" C0_proc3 3 "proc4" C1_proc4 4 "proc5" C1_proc5 5 .... ... Chương 3: Cơ chế dịch mã OOP sang mã máy

  40. Tạo bảng địa chỉ các tác vụ (tt) • Tạo bảng địa chỉ gồm C1METHCNT phần tử (C1METHCNT là số tác vụ của class hiện hành, kể cả các tác vụ thừa kế). • Mỗi phần tử được nhận dạng qua chỉ số và gồm 2 thông tin chính : tên gợi nhớ của tác vụ và địa chỉ của tác vụ. • copy bảng địa chỉ của class cha đã có. • Hiệu chỉnh lại các địa chỉ của các tác vụ bị override. • Thêm vào các tác vụ mới định nghĩa trong class hiện hành. Chương 3: Cơ chế dịch mã OOP sang mã máy

  41. 1 2 3 Dịch 1 method int C1_proc1(C1* p, int i, double d) { C2 o2; C2 *p2; // truy xuất thuộc tính p->C1_i = i; p->C1_d = d; // gọi hàm C1_proc5(p,d); C2_proc2(&o2, i,d); // gởi thông điệp : kiểm tra, load, // cập nhật bảng địa chỉ method for (i = 0; i <C2METHCNT; i ++) if (strcmp ("proc2", p2-> pvftbl[i].fname)==0) break; (*p2->pvftbl[i].faddr)(p2,i,d); }; int C1::proc1(int i,double k) { C2 o2; C2 *p2; C1::i = i; d = k; C1::proc5(d); o2.proc2(i,d); p2 = New(C2); p2->proc2(i,d); .... }; Chương 3: Cơ chế dịch mã OOP sang mã máy

  42. Dịch 1 method (tt) • tên method được chuyển từ dạng “tương đối” sang “tuyệt đối” (nối kết tên class vào). • thêm tham số đầu tiên cho hàm sinh ra : miêu tả tham khảo đến đối tượng mà hàm sẽ truy xuất các thuộc tính dữ liệu. • tên thuộc tính được chuyển từ dạng “tương đối” sang “tuyệt đối” (nối kết tên class vào). • gọi hàm internal  gọi hàm nhưng thêm tham số đầu tiên. • gởi thông điệp gồm 3 bước : • kiểm tra, tìm, load đối tượng rồi cập nhật bảng địa chỉ các method của đối tượng. • tìm chỉ số của method cần gọi trong bảng (i). • gọi gián tiếp method thông qua địa chỉ phần tử thứ i trong bảng. Chương 3: Cơ chế dịch mã OOP sang mã máy

  43. Tối ưu hóa code tạo ra • Có 2 vấn đề lớn trong quá trình dịch 1 class sang ngôn ngữ cổ điển. • Bảng địa chỉ các method chiếm nhiều không gian. • Tốn thời gian chạy lệnh gởi thông điệp : kiểm tra, tìm, load đối tượng, cập nhật bảng địa chỉ các tác vụ, tìm chỉ số method cần gọi và gọi gián tiếp qua địa chỉ trong bảng. • 1 số chương trình dịch tìm cách tối ưu hóa các vấn đề trên. • slide sau là các tối ưu hóa của chương trình dịch C++ và các giá phải trả. Chương 3: Cơ chế dịch mã OOP sang mã máy

  44. Tối ưu hóa code tạo ra (tt) • trong C++, tất cả đối tượng đều tạm thời và gắn chặt vào ứng dụng  bảng địa chỉ các method của các đối tượng luôn nằm sẵn trong không gian của ứng dụng. • Mỗi lần tạo đối tượng mới, biến pvftbl trong đối tượng được gán ngay địa chỉ bảng địa chỉ các method  không cần thực hiện bước 1 khi xử lý lệnh gởi thông điệp đến đối tượng. • C++ chỉ dùng mối quan hệ con/cha trong kiểm tra kiểu  công việc 2 (tìm chỉ số tác vụ) được làm tại thời điểm dịch thay vì tại thời điểm gởi thông điệp trong lúc chạy  cột tên gợi nhớ method không cần phải lưu trữ trong bảng địa chỉ các method. • chỉ có các virtual function mới được giải quyết theo cơ chế đa xạ  bảng địa chỉ chỉ chứa các hàm virtual của class, còn các function khác được dịch ra lời gọi hàm trực tiếp. Chương 3: Cơ chế dịch mã OOP sang mã máy

  45. Tối ưu hóa code tạo ra (tt) • cái giá phải trả của việc tối ưu hóa trong C++ : • người lập trình phải tự quyết định tác vụ nào cần xử lý theo cơ chế đa xạ, tác vụ nào không ? Nếu sự quyết định này sai thì sẽ gây lỗi khi chạy, mà là người thì khó lòng quyết định chính xác. • tính đa xạ chỉ đúng giữa các đối tượng có mối quan hệ con/cha, ở đó thứ tự các địa chỉ method của mọi class con trong bảng địa chỉ luôn giống thứ tự các method tương ứng của class cha, tuy nhiên giữa 2 class bất kỳ thì không thể đảm bảo  kiểm tra kiểu trong C++ không thể nâng cấp lên bằng cách dùng mối quan hệ "conformity". Chương 3: Cơ chế dịch mã OOP sang mã máy

  46. MÔN LẬP TRÌNH HƯỚNG ĐỐI TƯỢNG Chương 4 TỔNG QUÁT VỀ MỨC ĐỘ HỖ TRỢ OOP CỦA VC++ & JAVA Chương 4 : Tổng quát về mức độ hỗ trợ OOP của VC++ & Java

  47. 4.1 Ngôn ngữ Visual C++ 1. Chỉ hỗ trợ class, không hỗ trợ abstract type. 2. Cho phép đa thừa kế & Override method khi thừa kế. 3. Dùng 'abstract class' để định nghĩa interface. 4. Tầm vực truy xuất các thành phần. 5. Đa xạ có chọn lọc nhờ 'virtual function' 6. Chỉ hỗ trợ các đối tượng tạm. 7. Có thể định nghĩa “overloaded function”. Chương 4 : Tổng quát về mức độ hỗ trợ OOP của VC++ & Java

  48. Chỉ hỗ trợ class, không hỗ trợ abstract type Chỉ cung cấp lệnh “class” để đặc tả sự hiện thực của đối tượng, không có lệnh interface hay type để định nghĩa type của đối tượng. Dùng class để định nghĩa kiểu cho các biến, các thuộc tính. Cần phân biệt cách định nghĩa kiểu cho biến : C1 o1; // biến o1 là vùng nhớ chứa đối tượng C1* p1; // biến p1 là vùng nhớ chứa pointer tới đối tượng  • Nếu 1 class có chứa thuộc tính đối tượng thuộc kiểu class thì đối tượng tương ứng sẽ là đối tượng gộp vật lý đối tượng khác. • Nếu 1 class có chứa thuộc tính đối tượng thuộc kiểu class pointer thì đối tượng tương ứng sẽ là đối tượng gộp chứa tham khảo (pointer) đến đối tượng khác. Chương 4 : Tổng quát về mức độ hỗ trợ OOP của VC++ & Java

  49. Đa thừa kế Đa thừa kế trong định nghĩa class, hấp dẫn cho người lập trình nhưng chi phí hiện thực thì rất cao : • dễ gây ra việc trùng tên giữa các thành phần nằm trong các class cha khác nhau nhưng đều được thừa kế cho class con  phải giải quyết vấn đề trùng tên và tránh nhặp nhằng trong việc truy xuất chúng. • 1 class có thể chứa nhiều class cha trùng nhau  phải giải quyết việc duplicate các thành phần của các class cha trùng nhau này (dư thừa và mất tính nhất quán) VC++ đề nghị dùng "virtual base class" để tối ưu hóa bộ nhớ đối tượng. a. b. Chương 4 : Tổng quát về mức độ hỗ trợ OOP của VC++ & Java

  50. Đa thừa kế • Phát biểu : class NguoiCa : public Nguoi, public Ca {...}; sẽ tạo ra các đối tượng NguoiCa có cấu trúc dữ liệu theo hình a. trong slide trước  các thuộc tính trong class Sinhvat được nhân bản và tồn tại 2 lần ở 2 vị trí khác nhau trong đối tượng NguoiCa  dư thừa dữ liệu và mất tính nhất quán dữ liệu. • Còn phát biểu : • class NguoiCa : public virtual Nguoi, public virtual Ca {...}; sẽ tạo ra các đối tượng NguoiCa có cấu trúc dữ liệu theo hình b. trong slide trước  các thuộc tính trong class Sinhvat chỉ tồn tại 1 lần trong đối tượng NguoiCa  khắc phục được sự dư thừa dữ liệu và không mất tính nhất quán dữ liệu. Chương 4 : Tổng quát về mức độ hỗ trợ OOP của VC++ & Java

More Related