Cơ bản về hướng đối tượng và C++

Tổ chức thành các chương trình con(hay các module) ã Mỗi chương trình con đảm nhận xử lý một công việc nhỏ hay một nhóm công việc trong toàn bộ hệ thống ã Mỗi chương trình con này lại có thể chia nhỏ thành các chương trình con nhỏ hơn Chương trình = Cấu trúc dữ liệu + Giải thuật ã sử dụng các lệnh có cấu trúc: for, do, while, if then else . ã các ngôn ngữ: Pascal, C, . ã chương trình là tập các hàm/thủ tục ã Ưu điểm – chương trình được module hóa, do đó dễ hiểu, dễ bảo trì hơn – dễ dàng tạo ra các thư viện phần mềm 11

pdf31 trang | Chia sẻ: tlsuongmuoi | Lượt xem: 2160 | Lượt tải: 0download
Bạn đang xem trước 20 trang tài liệu Cơ bản về hướng đối tượng và C++, để xem tài liệu hoàn chỉnh bạn click vào nút DOWNLOAD ở trên
1• Bài giảng LTHĐT, Trần Minh Châu, Đại học Công nghệ ĐH Quốc gia HN , • Bài giảng LTHĐT, Nguyễn Việt Hà, Đại học Công nghệ ĐH Quốc gia HN , • Bài giảng LTHĐT, Nguyễn Ngọc Long, ĐH KHTN TPHCM • Bài giảng LTHĐT, Huỳnh Lê Tấn Tài, ĐH KHTN TPHCM • C++ How to Program, Dietel • ………………………. 2 • Tạo ra sản phẩm tốt một cách có hiệu quả • Nắm bắt được công nghệ 3 • Một số hệ Unix chứa khoảng 4M dòng lệnh • MS Windows chứa hàng chục triệu dòng lệnh • Người dùng ngày càng đòi hỏi nhiều chức năng, đặc biệt là chức năng thông minh • Phần mềm luôn cần được sửa đổi 4 • Cần kiểm soát chi phí – Chi phí phát triển Chi phí bảo trì– • Giải pháp chính là sử dụng lại(tái sử dụng) – Giảm chi phí và thời gian phát triển ấ– Nâng cao ch t lượng 5 • Cần dễ hiểu • Được coi là chính xác • Có giao diện rõ ràng • Tính module hóa • Không yêu cầu thay đổi khi sử dụng trong chương trình mới 6 • Lập trình không có cấu trúc • Lập trình có cấu trúc (lập trình thủ tục),hướng chức năng • Lập trình logic, lập trình hàm • Lập trình hướng đối tượng 7 • Là phương pháp xuất hiện đầu tiên – các ngôn ngữ như Assembly, Basic – sử dụng các biến toàn cục – lạm dụng lệnh GOTO • Các nhược điểm – khó hiểu, khó bảo trì, hầu như không thể sử dụng lại – chất lượng kém – chi phí cao – không thể phát triển các ứng dụng lớn 8 Ví dụ 10 k =1 20 gosub 100 30 if y > 120 goto 60 40 k = k+1 50 goto 20 60 print k y , 70 stop 100 3*k*k 7*k 3 y = + - 110 return 9 • Tổ chức thành các chương trình con(hay các module) • Mỗi chương trình con đảm nhận xử lý một công việc nhỏ hay một nhóm công việc trong toàn bộ hệ thống • Mỗi chương trình con này lại có thể chia nhỏ thành các chương trình con nhỏ hơn ấChương trình = C u trúc dữ liệu + Giải thuật 10 • sử dụng các lệnh có cấu trúc: for, do, while, if then else ... • các ngôn ngữ: Pascal, C, ... ủ• chương trình là tập các hàm/th tục • Ưu điểm – chương trình được module hóa, do đó dễ hiểu, dễ bảo trì hơn – dễ dàng tạo ra các thư viện phần mềm 11 Ví dụ struct Date { int year, mon, day; }; ... void print_date(Date d) { printf(”%d / %d / %d\n”, d.day,d.mon,d.year); } 12 • Nhược điểm – dữ liệu và mã xử lý là tách rời – người lập trình phải biết cấu trúc dữ liệu (vấn đề này một thời gian dài được coi là hiển nhiên) khi th đổi ấ t ú dữ liệ thì ã ử lý (th ật– ay c u r c u m x u toán) phải thay đổi theo – khó đảm bảo tính đúng đắn của dữ liệu – không tự động khởi tạo hay giải phóng dữ liệu động – không mô tả được đầy đủ, trung thực hệ thống trong thực tế 13 • Trong thế giới thực, chung quanh chúng ta là những đối tượng đó là các thực thể có mối, quan hệ với nhau. Ví dụ: các phòng trong một công ty • Lập trình hướng đối tượng (Object Oriented Programming LTHĐT) là phương pháp lập- trình lấy đối tượng làm nền tảng để xây dựng thuật giải xây dựng chương trình, 14 • Đối tượng (object): – Trong thế giới thực, khái niệm đối tượng được hiểu như là một thực thể: người, vật hoặc một bảng dữ liệu…. – Mỗi đối tượng sẽ tồn tại trong một hệ thống và có ý nghĩa nhất định trong hệ thống. – Đối tượng giúp biểu diễn tốt hơn thế giới thực trên máy tính 15 • Lớp: – Các đối tượng có các đặc tính tương tự nhau được gom chung lại thành lớp đối tượng Ví dụ. Người là một lớp đối tượng. Một lớp đối tượng được đặc trưng bằng các thuộc tính, và các hoạt động (hành vi, thao tác). – Thuộc tính (attribute) là một thành phần của đối tượng, có giá trị nhất định cho mỗi đối tượng tại mỗi thời điểm trong hệ thống. Vd: Tên, Tuổi, Cân à á ộ í ủ ờnặng l c c thu c t nh c a Ngư i – Thao tác (operation) thể hiện hành vi của một đối t tá độ l i ới á đối tượng c ng qua ạ v c c ượng khác hoặc với chính nó. 16 ỗ ố ể• M i thao tác trên một lớp đ i tượng cụ th tương ứng với một cài đặt cụ thể khác nhau. Một ài đặt h ậ đ i là ột hc n ư v y ược gọ m p ương thức (method). ể• Cùng một thao tác(phương thức) có th được áp dụng cho nhiều lớp đối tượng khác nhau, ột th tá h ậ đ i là ó tí h đm ao c n ư v y ược gọ c n a hình (polymorphism). ố ể• Một đ i tượng cụ th thuộc một lớp được gọi là một thể hiện (instance) của lớp đó. ổ ể– Joe Smith, 25 tu i, nặng 58kg, là một th hiện của lớp người. 17 • Ta dùng sơ đồ đối tượng để mô tả các lớp đối tượng. Sơ đồ đối tượng bao gồm sơ đồ lớp và sơ đồ thể hiện • Sơ đồ lớp mô tả các lớp đối tượng trong hệ thống, một lớp đối tượng được diễn tả bằng một hình chữ nhật có 3 phần: – phần đầu chỉ tên lớp, – phần thứ hai mô tả các thuộc tính – phần thứ ba mô tả các thao tác của các đối tượng trong lớp đó. 18 Sinh vieân Hoï teân N ê i h (Sinh vieân) Nguyeãn Vaên A 1984 Teân lôùp am s n Maõ soá Ñieåm TB 0610234T 9 2 Thuoäc tính Ñi hoïc Ñi thi . Thao taùc Phaân loaïi Sô ñoà lôùp Sô ñoà theå hieän ốĐ i tượng = Dữ liệu + Phương thức 19 • Các lớp đối tượng - Classes • Đóng gói – Encapsulation ế• Thừa k - Inheritance • Đa hình - Polymorphism 20 cách nhìn khái quát hóa về một tập các đối tượng có chung các đặc điểm được quan tâm (và bỏ qua những chi tiết không cần thiết). 21 • Đóng gói: Nhóm những gì có liên quan với nhau vào làm một, để sau này có thể dùng một cái tên để gọi đến – Các hàm/ thủ tục đóng gói các câu lệnh – Các đối tượng đóng gói dữ liệu của chúng và các thủ tục có liên quan • Che dấu thông tin: đóng gói để che một số thông tin và chi tiết cài đặt nội bộ để bên ngoài không nhìn thấy – che giấu những gì mà người dùng không cần – che giấu những gì mà mình cần giữ bí mật 22 • là cơ chế cho phép một lớp D có được các thuộc tính và thao tác của lớp C, như thể các thuộc tính và thao tác đó đã được định nghĩa tại lớp D. • cho phép cài đặt nhiều quan hệ giữa các đối tượng: đặc biệt hóa (“là”), khái quát hóa 23 cơ chế cho phép một tên thao tác hoặc thuộc tính có thể được định nghĩa tại nhiều lớp và có thể có nhiều cài đặt khác nhau tại mỗi lớp trong các lớp đó 24 • Cung cấp được những khả năng lập trình hướng đối tượng – cung cấp khả năng kiểm soát truy cập – kế thừa – đa hình 25 26 • OOM (Object Oriented Methodology): Phương pháp luận hướng đối tượng • OOA (Object Oriented Analysis): Phân tích hướng đối tượng. • OOD: Object Oriented Design (Thiết kế hướng đối tượng). • OOP: Object Oriented Programming (lập trình hướng đối tượng). • Inheritance: Kế thừa • Polymorphism: Đa hình • Encapsulation: Tính đóng gói. 27 • Nguyên lý kế thừa: tránh lặp, tái sử dụng. Ng ên lý đóng gói ha che dấ thông tin: h• uy y u c ương trình an toàn không bị thay đổi bới những đoạn chương trình khác • Dễ mở rộng, nâng cấp • Mô phỏng thế giới thực tốt hơn. 28 • Chương trình được chia thành các đối tượng. • Các cấu trúc dữ liệu được thiết kế sao cho đặc tả được đối tượng. • Các hàm thao tác trên các vùng dữ liệu của đối tượng được gắn với cấu trúc dữ liệu đó. 29 • Dữ liệu được đóng gói lại, được che giấu và không cho phép các hàm ngoại lai truy nhập tự do. • Các đối tượng tác động và trao đổi thông tin với nhau qua các hàm • Có thể dễ dàng bổ sung dữ liệu và các hàm mới vào đối tượng nào đó khi cần thiết • Chương trình được thiết kế theo cách tiếp cận từ d ới lê (b )ư n ottom-up . 30 – Mở rộng của C – Đầu thập niên 1980: Bjarne Stroustrup (Bell Laboratories) – Cung cấp khả năng lập trình hướng đối tượng • Objects • Object-oriented programs – Ngôn ngữ lai • C-like style • Object-oriented style • Both 31 • Chú thích • Các kiểu dữ liệu • Kiểm tra kiểu, đổi kiểu Ph i à kh i bá• ạm v v a o • Không gian tên ằ• H ng • Quản lý bộ nhớ ế• Tham chi u 32 #include void main() { int n; double d; char s[100]; cout << “Input an int, a double and a string ”;. cin >> n >> d >> s; cout << “n = “ << n << “\n”; t “d “ d “\ ”cou << = << << n ; cout << “s = “ << s << “\n”; } 33 Th hi á l ø ñò hæ ø hôù ñöô á h ùt h• am c eu a a c vung n ïc cap p a c o moät bieán. • Kyù hieäu & ñaët tröôùc bieán hoaëc haøm ñeå xaùc ñònh tham chieáu cuûa chuùng • Ví duï 1: int x = 10 *px = &x &y = x;– , , – *px = 20; // *px = x = y = 20 – y = 30; // y = x = *px = 30 • Ví du 2: ï – int arrget(int *a, int i) { return a[i]; } – arrget(a, 1) = 1; // a[1] = 1; – cin >> arrget(a,1); // cin >> a[1]; • Ví duï 3: – void swap1(int x, int y) { int t = x; x = y; y = t; } – void swap2(int *x, int *y) { int *t = x; x = y; y = t; } – void swap3(int &x, int &y) { int t = x; x = y; y = t; } 34 Choàng haøm (Functions overloading int abs(int i); long labs(long l); double fabs(double d); int abs(int i); long abs(long l); double abs(double d); int abs(int i) { return abs(i);} long abs(long l) { return labs(l);} double abs(double d) { return fabs(d);} void test_abs() { int i = abs(10); // abs(int ) long l = abs(-10l); // abs(long ) double = abs(0.1l); // abs(double ) } 35 Tham soá ngaàm ñònh trong lôøi goïi haøm void inc(int &a, int b = 1) { a = a + b; } int x = 5, y = 10; inc(x 10); // x = x + 10 Chuù yù: , inc(y); // y = y + 1 – Caùc tham soá coù giaù trò ngaàm ñònh phaûi ñaët cuoái danh saùch tham soá, ñeå traùnh nhaàm laãn caùc giaù trò. – Caùc giaù trò ngaàm ñònh cuûa tham soá chæ ñöôïc khai baùo trong khuoân maãu haøm 36 • Toaùn töû caáp phaùt boä nhôù ñoäng new int *x; x = new int; // x = (int*)malloc(sizeof(int)); char *y; y = new char[100]; // y = (char*)malloc(100); • Toaùn töû giaûi phoùng vuøng nhôù ñoäng delete delete x; // free(x); delete y; // free(y); 37 • Nên khai báo hằng đối với: Các đối tượng mà ta không định sửa đổi– – const double PI = 3.14; – const Date openDate(18,8,2003); – Các tham số của hàm mà ta không định cho hàm đó sửa đổi id i tH i ht( t L Obj &LO)– vo pr n e g cons arge { cout << LO.height; } – Các hàm thành viên không thay đổi đối tượng chủ – int Date::getDay() const { return day; } 38 • Một lớp bao gồm các thành phần dữ liệu hay là thuộc tính và các phương thức hay là hàm thành phần • Lớp trong C++ thực chất là một kiểu dữ liệu do người sử dụng định nghĩa 39 • Lưu giữ trạng thái: mỗi đối tượng có trạng thái (dữ liệu của nó) và các thao tác • Định danh: Mỗi đối tượng bất kể đang ở trạng thái nào đều có định danh và được đối xử như một thực thể riêng biệt. • Thông điệp: là phương tiện để một đối tượng A chuyển tới đối tượng B yêu cầu B thực hiện một trong số các thao tác của B. 40 • Lớp: là khuôn mẫu để tạo các đối tượng (tạo các thể hiện). Mỗi đối tượng có cấu trúc và hành vi giống như lớp đối tượng mà nó được tạo từ đó. • Lớp là cái ta thiết kế và lập trình Đối t là ái t t (từ ột lớ ) t i thời i• ượng c a ạo m p ạ g an chạy. 41 class { private: <khai báo các thành phần riêng trong từng đối tượng> protected: <khai báo các thành phần riêng trong từng đối tượng, có thể truy cập từ lớp dẫn xuất > public: <khai báo các thành phần giao tiếp của từng đối tượng> }; <đị h hĩ ủ á hà thà h hầ h đn ng a c a c c m n p n c ưa ược định nghĩa bên trong khai báo lớp> 42 :: (<danh sách tham số>) { } void point::display() { } …….. 43 • Tạo đối tượng: = new • Gọi hàm thành phần của lớp (<d hn ư ng . n m n p n an sách các tham số nếu có>); Æ<tên hàm thành phần>(); 44 • Xây dựng lớp Điểm (Point) trong hình học 2D – Thuộc tính • Tung độ • Hoành độ – Thao tác (phương thức) • Khởi tạo • Di chuyển • In ra màn hình • ………….. 45 /* i t */po n .cpp #include #include class point { /*khai báo các thành phần dữ liệu riêng*/ private: int x,y; /*khai báo các hàm thành phần công cộng*/ public: void init(int ox, int oy); id (i t d i t d )vo move n x, n y ; void display(); }; 46 void point::init(int ox, int oy) { cout<<"Ham thanh phan init\n"; x = ox; y = oy; /*x,y là các thành phần của đối tượng gọi hàm thành phần*/ } void point::move(int dx, int dy) { cout<<"Ham thanh phan move\n"; x += dx; y += dy; } void point::display() { cout<<"Ham thanh phan display\n"; cout<<"Toa do: "<<x<<" "<<y<<"\n"; } 47 void main() { clrscr(); point p; p.init(2,4); /*gọi hàm thành phần từ đối tượng*/ p.display(); p.move(1,2); p.display(); getch(); } 48 Ham thanh phan init Ham thanh phan display Toa do: 2 4 H th h ham an p an move Ham thanh phan display 3 6Toa do: 49 • Trong định nghĩa của lớp ta có thể xác định khả năng truy xuất thành phần của một lớp nào đó từ bên ngoài phạm vi lớp • private và public là các từ khoá xác định thuộc tính truy xuất • Mọi thành phần được liệt kê trong phần public đều có thể truy xuất trong bất kỳ hàm nào • Những thành phần được liệt kê trong phần private chỉ được truy xuất bên trong phạm vi lớp 50 • Trong lớp có thể có nhiều nhãn private và public • Mỗi nhãn này có phạm vi ảnh hưởng cho đến khi gặp một nhãn kế tiếp hoặc hết khai báo lớp • Nhãn private đầu tiên có thể bỏ đi vì C++ ngầm hiểu rằng các thành phần trước nhãn public đầu tiên là private 51 class tamgiac{ i tpr va e: float a,b,c;/*độ dài ba cạnh*/ public: void nhap();/*nhập vào độ dài ba cạnh*/ void in();/*in ra các thông tin liên quan đến tam giác*/ private: int loaitg();/*cho biết kiểu của tam giác: 1-d,2-vc,3-c,4-v,5-t*/ float dientich();/*tính diện tích của tam giác*/ }; 52 class tamgiac{ private: float a b c;/*độ dài ba cạnh*/ , , int loaitg();/*cho biết kiểu của tam giác: 1-d,2-vc,3-c,4-v,5-t*/ float dientich();/*tính diện tích của tam giác*/ public: void nhap();/*nhập vào độ dài ba cạnh*/ void in();/*in ra các thông tin liên quan đến tam giác*/ }; 53 Đối tượng như tham số của hàm thành phần • Hàm thành phần có quyền truy nhập đến các thành phần private của đối tượng gọi nó: void point::init(int xx,int yy) { x=xx; y=yy; } 54 Đối tượng như tham số của hàm thành phần • Hàm thành phần có quyền truy nhập đến tất cả các thành phần private của các đối tượng, tham chiếu đối tượng hay con trỏ đối tượng có cùng kiểu lớp khi được dùng là tham số hình thức của nó int trung(point pt) {return(x==pt.x && y==pt.y);} int trung(point *pt) {return(x==pt->x && y==pt->y);} int trung(point &pt) {return(x==pt.x && y==pt.y);} 55 • Từ khoá this trong định nghĩa của các hàm thành phần lớp dùng để xác định địa chỉ của đối tượng dùng làm tham số ngầm định cho hàm thành phần • Con trỏ this tham chiếu đến đối tượng đang gọi hàm thành phần int trung(point pt) {return(this->x==pt.x && this->y==pt.y);} 56 point a, b; việc sao chép giá trị các thành phần ốa.init(5,2); b=a; dữ liệu (x, y) từ đ i tượng a sang đối tượng b tương ứng từng đôi một ba 5 x5x 2 y2y 57 • Nếu hai đối tượng A và B cùng kiểu, có các thành phần dữ liệu x,y(tĩnh) và z là một con trỏ chỉ đến một vùng nhớ được cấp phát động ba 2 y 5 5 2 x y x zzSao chép bề mặt vùng dữ liệu động58 • Constructor là một loại phương thức đặc biệt dùng để khởi tạo thể hiện của lớp • Bất kể loại cấp phát bộ nhớ nào được sử dụng (tự động tĩnh động) mỗi khi một thể hiện của, , , lớp được tạo, một hàm constructor nào đó của lớp sẽ được gọi 59 class point { /*khai báo các thành phần dữ liệu*/ int x; int y; public: /*khai báo các thành phần hàm*/ point(int ox,int oy) {x=ox;y=oy;}/*hàm thiết lập*/ void move(int dx,int dy) ; void display(); }; point a(5,2); //int i(5) 60 • Constructor có cùng tên với tên của lớp • Constructor không có giá trị trả về (kể cả void) • Constructor phải có thuộc tính public C t t ó thể đ kh i bá hồ h• ons ruc or c ược a o c ng n ư các hàm C++ thông thường khác Constructor có thể được khai báo với các tham• số có giá trị ngầm định 61 class point { /*khai báo các thành phần dữ liệu*/ int x; int y; public: /*khai báo các thành phần hàm*/ point() {x=0;y=0}; point(int ox,int oy) {x=ox;y=oy;}/*hàm thiết lập*/ void move(int dx,int dy) ; void display(); }; point a(5,2); point b; point c(3); 62 class point { /*khai báo các thành phần dữ liệu*/ int x; int y; public: /*khai báo các thành phần hàm*/ point() {x=0;y=0}; point(int ox,int oy=1) {x=ox;y=oy;}/*hàm thiết lập*/ void move(int dx,int dy) ; void display(); }; point a(5,2); point b; point c(3); 63 • Constructor mặc định (default constructor) là constructor được gọi khi thể hiện được khai báo ố ố ấmà không có đ i s nào được cung c p • MyClass x; M Cl * M Cl• y ass p = new y ass; • Ngược lại, nếu tham số được cung cấp tại khai báo thể hiện trình biên dịch sẽ gọi phương thức , constructor khác (overload) • MyClass x(5); • MyClass* p = new MyClass(5); 64 • Đối với constructor mặc định, nếu ta không cung cấp một phương thức constructor nào, C++ sẽ tự sinh constructor mặc định là một phương thức rỗng ế• Tuy nhiên, n u ta không định nghĩa constructor mặc định nhưng lại có các constructor khác, trình biên dịch sẽ báo lỗi không tìm thấy constructor mặc định nếu ta không cung cấp tham số khi tạo thể hiện. 65 class point { /*khai báo các thành phần dữ liệu*/ int x; int y; public: ầ/*khai báo các thành ph n hàm*/ point(int ox,int oy=1) {x=ox;y=oy;}/*hàm thiết lập*/ void move(int dx int dy) ; , void display(); }; point a(5,2); point b; point c(3); 66 class point { /*khai báo các thành phần dữ liệu*/ int x; int y; public: /*khai báo các thành phần hàm*/ point(int ox=0,int oy=0) {x=ox;y=oy;}/*hàm thiết lập*/ void move(int dx,int dy) ; void display(); }; point a(5 2); , point b; point c(3); 67 68 • Cũng như một phương thức constructor được gọi khi một đối tượng được tạo, loại phương thức thứ hai, destructor, được gọi ngay trước khi thu hồi một đối tượng • Destructor thường được dùng để thực hiện mọi việc dọn dẹp cần thiết trước khi một đối tượng bị huỷ • Destructor không có giá trị trả về, và không thể định ốnghĩa lại (nó không bao giờ có tham s ) • Phương thức destructor trùng tên với tên lớp nhưng có dấu ~ đặt trước • Destructor phải có thuộc tính public 69 class vector { i t // ố hiền n; s c u float *v; //vùng nhớ toạ độ public: vector(); //Hàm thiết lập không tham số vector(int size); //Hàm thiết lập một tham số vector(int size, float *a); ~vector();//Hàm huỷ bỏ luôn luôn không có tham số , void display(); }; 70 • Giả sử có lớp Vector, lớp Matrix • Cần viết hàm nhân 1 Vector và 1 Matrix • Hàm nhân: Khô thể th ộ lớ V t– ng u c p ec or – Không thể thuộc lớp Matrix Không thể tự do– • Giải pháp: xây dựng hàm truy cập dữ liệu. 71 • Hàm bạn không thuộc lớp, nhưng có quyền truy cập các thành viên private. • Khi định nghĩa một lớp, có thể khai báo rằng một hay nhiều hàm “bạn” (bên ngoài lớp) • Ưu điểm: kiểm soát các truy nhập ở cấp độ lớp - không thể áp đặt hàm bạn cho một lớp nếu điều đó không được dự trù trước trong khai báo của lớp 72 • Hàm tự do là bạn của một lớp. • Hàm thành phần của một lớp là bạn của một lớp khác. • Hàm bạn của nhiều lớp . • Tất cả các hàm thành phần của một lớp là bạn của một lớp khác 73 class point { int x y; , public: point(int abs =0 int ord =0) { , x = abs;y = ord; } friend int coincide (point,point); }; 74 • Vị trí của khai báo “bạn bè” trong lớp hoàn toàn tuỳ ý • Trong hàm bạn, không còn tham số ngầm định this như trong hàm thành phần • Hàm bạn của một lớp có thể có một hay nhiều tham số, hoặc có giá trị trả về thuộc kiểu lớp đó 75 76 • Các phương thức truy vấn (query method) là các phương thức dùng để hỏi về giá trị của các thành viên dữ liệu của một đối tượng • Có nhiều loại câu hỏi truy vấn có thể: tr ấn đơn giản (“giá trị của là bao nhiê ?”)– uy v x u – truy vấn điều kiện (“thành viên x có lớn hơn 10 không?”) – truy vấn dẫn xuất (“tổng giá trị của các thành viên x và y là bao nhiêu?”) • Đặc điểm quan trọng của phương thức truy vấn là nó không nên thay đổi trạng thái hiện tại của đối tượng 77 • Đối với các truy vấn đơn giản, quy ước đặt tên phươngthức: tiền tố “get” tiếp theo là tên của , thành viên • int getX(); • int getSize(); • Các loại truy vấn khác nên có tên có tính mô tả • Truy vấn điều kiện nên có tiền tố “is” 78 • Ngược lại với truy vấn, các phương thức cập nhật thường thay đổi trạng thái của đối tượng bằng cách sửa đổi một hoặc nhiều thành viên dữ liệu của đối tượng đó D đ iả hấ ủ á h hứ ậ• ạng ơn g n n t c a c c p ương t c c p nhật là gán một giá trị nào đó cho một thành viên dữ liệu • Đối với dạng cập nhật đơn giản, quy ước đặt tên: dùng tiền tố “set” kèm theo tên thành viên ầc n sửa • int setX(int); 79 • Nếu các phương thức get/set chỉ có nhiệm vụ cho ta đọc và ghi giá trị cho các thành viên dữ liệu, quy định các thành viên private để được ích lợi gì? • Ngoài việc bảo vệ các nguyên tắc đóng gói, ta còn cần kiểm tra xem giá trị mới cho thành viên dữ liệu có hợp lệ hay không. • Sử dụng phương thức truy vấn cho phép ta thực ể ổhiện việc ki m tra trước khi thực sự thay đ i giá trị của thành viên. • Cho phép chỉ các dữ liệu có thể truy vấn hay thay đổi được truy cập đến. 80 int Student::setGPA(double newGPA) { if ((newGPA >= 0.0) && (newGPA <= 4.0)) { this->gpa = newGPA; return 0; // Return 0 to indicate success } else { return -1; // Return -1 to indicate failure } } 81 • Đối với class, static dùng để khai báo thành viên dữ liệu dùng chung cho mọi thể hiện của lớp. • một bản duy nhất tồn tại trong suốt quá trình chạy của chương trình, • dùng chung cho tất cả các thể hiện của lớp, ấ ể ể• b t k lớp đó có bao nhiêu th hiện 82 • Đếm số đối tượng MyClass 83 84 85 • Từ khoá const được dùng cho các tham số của hàm để đảm bảo các tham số được truyền cho hà ẽ khô bị hà ử đổim s ng m s a . • int myFunction(const int& x); Còn tham số ẩn truyền bằng con trỏ this và• chính là đối tượng chủ? 86 • Xeùt ñoaïn chöông trình sau: #include void main() { cout << "Hello world \n"; , . } Haõy söûa lai ñoan chöông trình treân ñeå coù xuaát lieäu: ï ï Entering a C++ program saying... Hello, world. And then exitting… Yeâu caàu khoâng thay ñoåi haøm main() döôùi baát kyø hình thöùc naøo. 87 • Ñoaïn chöông trình ñöôïc söûa laïi nhö sau #include class Dummy { public: Dummy() {cout << "Entering a C++ program saying...\n";} ~Dummy() {cout << "And then exitting...";} }; Dummy A; void main() { cout << "Hello, world.\n"; } 88 • Ñoái töông coù theå laø thaønh phaàn cuûa ñoái töông khaùc, ï ï khi moät ñoái töôïng thuoäc lôùp “lôùn” ñöôïc taïo ra, caùc thaønh phaàn cuûa noù cuõng ñöôïc taïo ra. Phöông thöùc thieát laäp (neáu coù) seõ ñöôïc töï ñoäng goïi cho caùc ñoái töôïng thaønh phaàn. • Neáu ñoái töôïng thaønh phaàn phaûi ñöôïc cung caáp tham soá khi thieát laäp thì ñoái töôïng keát hôïp (ñoái töôïng lôùn) phaûi coù phöông thöùc thieát laäp ñeå cung caáp tham soá thieát laäp cho caùc ñoái töôïng thaønh phaàn. 89 • Cuù phaùp ñeå khôûi ñoäng ñoái töông thaønh phaàn laø duøng ï daáu hai chaám (:) theo sau bôûi teân thaønh phaàn vaø tham soá khôûi ñoäng. • Khi ñoái töôïng keát hôïp bò huyû ñi thì caùc ñoái töôïng thaønh phaàn cuûa noù cuõng bò huyû ñi, nghóa laø phöông thöùc huyû boû seõ ñöôïc goïi cho caùc ñoái töôïng thaønh phaàn, sau khi phöông thöùc huyû boû cuûa ñoái töôïng keát hôïp ñöôïc goïi. 90 class Diem { double x,y; public: Diem(double xx, double yy) {x = xx; y = yy;} // ... }; class TamGiac { Diem A,B,C; public: void Ve() const; // ... }; TamGiac t; // Bao sai Diem D; 91 class String { char *p; public: String(char *s) {p = strdup(s);} String(const String &s) {p = strdup(s.p);} ~String() {cout << "delete "<< (void *)p << "\n"; delete [] p; //... }; class SinhVien { String MaSo; String HoTen; int NamSinh; public: }; SinhVien s; // Bao sai 92 class Diem { double x,y; public: Diem(double xx, double yy {x = xx; y = yy;} // ... }; 93 class TamGiac { Diem A,B,C; public: TamGiac(double xA, double yA, double xB, double yB, double xC, double yC):A(xA,yA), B(xB,yB),C(xC,yC){} void Ve() const; // ... }; TamGiac t(100,100,200,400,300,300); 94 class String { char *p; public: String(char *s) {p = strdup(s);} String(const String &s) {p = strdup(s.p);} ~String() {cout << "delete "<< (void *)p << "\n"; delete [] p; //... }; 95 class SinhVien { String MaSo; String HoTen; int NamSinh; public: SinhVien(char *ht, char *ms, int ns):HoTen(ht), MaSo(ms){NamSinh = ns;} //... }; SinhVien s(“Nguyen Van Beo”, “19920005”, 1985); //Ok 96 Khôûi ñoäng ñoái töôïng thaønh phaàn: Duøng daáu hai chaám (:) • Cuù phaùp duøng daáu hai chaám cuõng ñöôïc duøng cho ñoái töôïng thaønh phaàn thuoäc kieåu cô baûn. class Diem { double x,y; public: Diem(double xx, double yy):x(xx), y(yy){} // ... }; class SinhVien { String MaSo, HoTen; int NamSinh; public: SinhVien(char *ht, char *ms, int ns):HoTen(ht), MaSo(ms) NamSinh(ns){}, //... }; 97 • Khi ñoái töôïng keát hôïp bò huyû boû, caùc ñoái töôïng thaønh phaàn cuûa noù cuõng bò huyû boû. class SinhVien { String MaSo HoTen; , int NamSinh; int SoMon; double *Diem; public: SinhVien(char *ht, char *ms, int ns, int sm, double *d); ~SinhVien() {delete [] Diem;} //... }; SinhVien::SinhVien(char *ht, char *ms, int ns, int sm, double *d):HoTen(ht), MaSo(ms), NamSinh(ns), SoMon(sm) { memcpy(Diem = new double[SoMon], d, SoMon*sizeof(double)); } 98 • Khi moät maûng ñöôïc taïo ra, caùc phaàn töû cuûa noù cuõng ñöôïc taïo ra, do ñoù phöông thöùc thieát laäp seõ ñöôïc goïi cho töøng phaàn töû moät. • Vì khoâng theå cung caáp tham soá khôûi ñoäng cho taát caû caùc phaàn töû cuûa maûng neân khi khai baùo maûng, moãi ñoái töôïng trong maûng phaûi coù khaû naêng töï khôûi ñoäng, nghóa laø coù theå ñöôïc thieát laäp khoâng caàn tham soá. • Ñoái töông coù khaû naêng tö khôûi ñoäng trong caùc tröôøng hôp ï ï ï sau: – Lôùp khoâng coù phöông thöùc thieát laäp. – Lôùp coù phöông thöùc thieát laäp khoâng tham soá. – Lôùp coù phöông thöùc thieát laäp maø moïi tham soá ñeàu coù giaù trò maëc nhieân. 99 class Diem { double x,y; public: Diem(double xx, double yy):x(xx), y(yy) {} void Set(double xx, double yy) {x = xx, y = yy;} // ... }; class String { char *p; ipubl c: String(char *s) {p = strdup(s);} String(const String &s) {p = strdup(s.p);} String() {~ cout << "delete "<< (void *)p << "\n"; delete [] p; } // ... 100 class SinhVien { String MaSo; String HoTen; int NamSinh; public: SinhVien(char *ht, char *ms, int ns):HoTen(ht), MaSo(ms), i h( ){}NamS n ns //... }; String as[3]; // Bao sai Diem ad[5]; // Bao sai SinhVien asv[7]; // Bao sai 101 class Diem { double x,y; public: i (d bl d bl ) ( ) ( ){}D em ou e xx = 0, ou e yy = 0 :x xx , y yy void Set(double xx, double yy) {x = xx, y = yy;} // ... }; class String { char *p; public: String(char *s = “”) {p = strdup(s);} String(const String &s) {p = strdup(s.p);} ~String() {cout << "delete "<< (void *)p << "\n"; delete [] p;} // ... 102 class SinhVien { String MaSo; String HoTen; i i hnt NamS n ; public: SinhVien(char *ht = “Nguyen Van A”, char *ms = “19920014” int ns 1982):HoTen(ht), = , MaSo(ms), NamSinh(ns){} //... }; String as[3]; // Ok: Ca ba phan tu deu la chuoi rong Diem ad[5]; // Ok: ca 5 diem deu la (0,0) SinhVien asv[7]; // Ok: Het sai ca 7 sinh vien deu co cung hoten, maso, namsinh 103 class Diem { double x,y; public: i (d bl d bl ) ( ) ( ){}D em ou e xx, ou e yy :x xx , y yy Diem():x(0), y(0){} // ... }; class String { char *p; public: String(char *s) {p = strdup(s);} String() {p = strdup(“”);} ~String() {cout << "delete "<< (void *)p << "\n"; delete [] p;} // ... 104 class SinhVien { String MaSo; String HoTen; int NamSinh; public: SinhVien(char *ht, char *ms, int ns):HoTen(ht), MaSo(ms), NamSinh(ns){} SinhVien():HoTen(“Nguyen Van A”), MaSo(“19920014”), NamSinh(1982){} //... }; String as[3]; // Ca ba phan tu deu la chuoi rong Diem ad[5]; // ca 5 diem deu la (0,0) i h i [ ] // i h i d hS n V en asv 7 ; Ca 7 s n v en eu co cung oten, maso, namsinh 105 • Ñoái töông ñöôc caáp phaùt ñoäng laø caùc ñoái töông ñöôc ï ï ï ï taïo ra baèng pheùp toaùn new vaø bò huyû ñi baèng pheùp toaùn delete • Pheùp toaùn new caáp ñoái töôïng trong vuøng heap (hay vuøng free store) vaø goi phöông thöùc thieát laäp cho ï ñoái töôïng ñöôïc caáp. • Duøng new coù theå caáp moät ñoái töông vaø duøng delete ï ñeå huyû moät ñoái töôïng. • Duøng new vaø delete cuõng coù theå caáp nhieàu ñoái töôïng vaø huyû nhieàu ñoái töôïng. 106 class String { char *p; public: String(char *s) {p = strdup(s);} String(const String &s) {p = strdup(s.p);} ~String() {delete [] p;} //... }; class Diem { double x,y; public: Diem(double xx, double yy):x(xx),y(yy){}; //... }; //... 107 int *pi = new int; int *pj = new int(15); Diem *pd = new Diem(20,40); String *pa = new String("Nguyen Van A"); //... delete pa; delete pd; delete pj; delete pi; 108 • Trong tröôøng hôïp caáp nhieàu ñoái töôïng, ta khoâng theå cung caáp tham soá cho töøng phaàn töû ñöôc caáp: ï int *pai = new int[10]; Diem *pad = new Diem[5]; // Bao sai String *pas = new String[5]; // Bao sai • Thoâng baùo loãi cho ñoaïn chöông trình treân nhö sau: Cannot find default constructor to initialize array element of type 'Diem' Cannot find default constructor to initialize array element of type String’ • Loãi treân ñöôïc khaéc phuïc baèng caùch cung caáp phöông thöùc thieát laäp ñeå ñoái töông coù khaû naêng töï ï khôûi ñoäng. 109 class String { char *p; public: String(char *s = "Alibaba") {p = strdup(s);} String(const String &s) {p = strdup(s.p);} ~String() {delete [] p;} //... }; class Diem { double x,y; public: Diem(double xx, double yy):x(xx),y(yy){}; Diem():x(0),y(0){}; //... }; 110 • Khi ñoù moïi phaàn töû ñöôïc caáp ñeàu ñöôïc khôûi ñoäng vôùi cuøng giaù trò i i i [ ]nt *pa = new nt 10 ; Diem *pad = new Diem[5]; // ca 5 diem co cung toa do (0,0) String *pas new String[5] = ; // Ca 5 chuoi cung duoc khoi dong bang “Alibaba” • Vieäc huyû nhieàu ñoái töôïng ñöôïc thöïc hieän baèng caùch duøng delete vaø coù theâm daáu [] ôû tröôùc . – delete [] pas; – delete [] pad; d l t [] i– e e e pa ; • (?) Coù theå thay ba phaùt bieåu treân baèng moät phaùt bieåu duy nhaát sau ñöôïc khoâng ? delete pas,pad,pai; // ?? 111 • Lôùp coù hai phaàn taùch rôøi, moät laø phaàn giao dieän khai baùo trong phaàn public ñeå ngöôøi söû duïng “thaáy” vaø söû duïng, vaø hai laø chi tieát caøi ñaët bao goàm döõ lieäu khai baùo trong phaàn private cuûa lôùp vaø chi tieát maõ hoaù caùc haøm thaønh phaàn, voâ hình ñoái vôùi ngöôøi duøng. • Ta coù theå thay ñoåi uyeån chuyeån chi tieát caøi ñaët, nghóa laø coù theå thay ñoåi toå chöùc döõ lieäu cuûa lôùp, cuõng nhö coù theå thay ñoåi chi tieát thöc hieän caùc haøm thaønh phaàn (do sö thay ñoåi toå ï ï chöùc döõ lieäu hoaëc ñeå caûi tieán giaûi thuaät). Nhöng neáu baûo ñaûm khoâng thay ñoåi phaàn giao dieän thì khoâng aûnh höôûng ñeán øi û d ø d ñ ù kh â l ø ñ å õ ki á t ù û h ängöô sö uïng, va o o ong am o vô en ruc cua e thoáng. • Lôùp ThoiDiem coù theå ñöôc caøi ñaët vôùi caùc thaønh phaàn döõ ï lieäu laø giôø, phuùt, giaây hoaëc toång soá giaây tính töø 0 giôø. 112 class ThoiDiem { int gio, phut, giay; static bool HopLe(int g, int p, int gy); public: ThoiDiem(int g = 0, int p = 0, int gy = 0) {Set(g,p,gy);} void Set(int g, int p, int gy); int LayGio() const {return gio;} int LayPhut() const {return phut;} int LayGiay() const {return giay;} void Nhap(); void Xuat() const; void Tang(); void Giam(); }; 113 class ThoiDiem { long tsgiay; static bool HopLe(int g, int p, int gy); public: ThoiDiem(int g = 0, int p = 0, int gy = 0) {Set(g,p,gy);} void Set(int g, int p, int gy); int LayGio() const {return tsgiay / 3600;} int LayPhut() const {return (tsgiay%3600)/60;} int LayGiay() const {return tsgiay % 60;} void Nhap(); void Xuat() const; void Tang(); void Giam(); }; 114 • Khi ta coù theå nghó ñeán “noù” nhö moät khaùi nieäm rieâng reõ, xaây döïng lôùp bieåu dieãn khaùi nieäm ñoù. Ví duï lôùp SinhVien. • Khi ta nghó ñeán “noù” nhö moät thöïc theå rieâng reõ, taïo ñoái töôïng thuoäc lôùp. Ví duï ñoái töôïng Sinh vieân “Nguyen Van A” (vaø caùc thuoäc tính khaùc nhö maõ soá naêm sinh ) , … . • Lôùp laø bieåu dieãn cuï theå cuûa moät khaùi nieäm, vì vaäy lôùp luoân luoân laø DANH TÖØ. • Caùc thuoäc tính cuûa lôùp laø caùc thaønh phaàn döõ lieäu, neân chuùng luoân luoân laø DANH TÖØ. C ù h ø h ø h h à l ø ù h ù hæ õ h ñ ä û l ù• ac am t an p an a cac t ao tac c ro oaït ong cua ôp neân caùc haøm naøy laø ÑOÄNG TÖØ. • Caùc thuoäc tính döõ lieäu phaûi vöøa ñuû ñeå moâ taû khaùi nieäm, khoâng dö, khoâng thieáu. 115 ƒ Caùc thuoäc tính coù theå ñöôïc suy dieãn töø nhöõng thuoäc tính khaùc thì duøng haøm thaønh phaàn ñeå thöïc hieän tính toaùn. Chu vi, dieän tích tam giaùc laø thuoäc tính suy dieãn // SAI // DUNG . class TamGiac { Diem A,B,C; class TamGiac { double ChuVi, DienTich; public: Diem A,B,C; bli//... }; pu c: //... double ChuVi()const; double DienTich() const; } 116 • Caù bieät coù theå coù moät soá thuoäc tính suy dieãn ñoøi hoûi nhieàu taøi nguyeân hoaëc thôøi gian ñeå thöïc hieän tính toaùn, ta coù theå khai baùo laø döõ lieäu thaønh phaàn. Ví duï tuoåi trung bình cuûa daân Vieät Nam. class QuocGia { long DanSo; double DienTich; double TuoiTrungBinh; //... public: double TinhTuoiTB() const; //... }; 117 • Chi tieát caøi ñaët, bao goàm döõ lieäu vaø phaàn maõ hoaù caùc haøm thaønh phaàn coù theå thay ñoåi uyeån chuyeån nhöng phaàn giao dieän, nghóa laø phaàn khai baùo caùc haøm thaønh phaàn caàn phaûi coá ñònh ñeå khoâng aûnh höôûng ñeán ngöôøi söû dung Tuy nhieân ï neân coá gaéng caøi ñaët döõ lieäu moät caùch töï nhieân theo ñuùng khaùi nieäm.// NEN // KHONG NEN class PhanSo { int tu mau; class PhanSo { long tu_mau; , public: //... }; public: //... }; 118 D õ li ä h ø h h à â ñ k á h h ì h â• ö eu t an p an nen öôïc et ôïp t ay v p an raõ // NEN // KHONG NEN class TamGiac { Diem A,B,C; class TamGiac { double xA, yA, xB, yB, public: //... }; xC, yC; public: //... class HinhTron { Diem Tam; }; class HinhTron { double BanKinh; public: //... double tx, ty, BanKinh; public: // }; ... }; 119 • Chi tieát caøi ñaët, bao goàm döõ lieäu vaø phaàn maõ hoaù caùc haøm thaønh phaàn coù theå thay ñoåi uyeån chuyeån nhöng phaàn giao dieän, nghóa laø phaàn khai baùo caùc haøm thaønh phaàn caàn phaûi coá ñònh ñeå khoâng aûnh höôûng ñeán ngöôøi söû duïng (xem phaàn 2 4). . • Döõ lieäu thaønh phaàn neân ñöôïc keát hôïp thay vì phaân raõ// NEN class TamGiac // KHONG NEN class TamGiac { Diem A,B,C; public: { double xA, yA, xB, yB, xC, yC; //... }; public: //... }; 120 • Trong moïi tröôøng hôïp, neân coù phöông thöùc thieát laäp ñeå khôûi ñoäng ñoái töôïng. • Neân coù phöông thöùc thieát laäp coù khaû naêng töï khôûi ñoäng khoâng caàn tham soá. • Neáu ñoái töôïng coù nhu caàu caáp phaùt taøi nguyeân thì phaûi coù phöông thöùc thieát laäp, phöông thöùc thieát laäp åsao cheùp ñe khôûi ñoäng ñoái töôïng baèng ñoái töôïng cuøng kieåu vaø coù phöông thöùc huyû boû ñeå doïn deïp. øi ø h ûi ù h ù ù ( h i á h )Ngoa ra con p a co p ep gan c öông t ep t eo . • Ngöôïc laïi, ñoái töôïng ñôn giaûn khoâng caàn taøi nguyeân à árieâng thì khoâng can phöông thöùc thiet laäp sao cheùp vaø cuõng khoâng caàn phöông thöùc huyû boû. 121

Các file đính kèm theo tài liệu này:

  • pdfCơ bản về hướng đối tượng và C++.pdf
Tài liệu liên quan