TÀI LIỆU ĐẠI HỌC - godautre PPLT-Chuong 3 tài liệu, giáo án, bài giảng , luận văn, luận án, đồ án, bài tập lớn về tất cả...
Trang 1Chương 3
Lập trình hướng đối tượng
Trang 2• Là phương pháp lập trình hỗ trợ công nghệ đối tượng
• OOP được xem là giúp tăng năng suất, đơn giản hóa độ phức tạp khi bảo trì cũng như mở rộng phần mềm bằng cách cho phép lập trình viên tập trung vào các đối tượng phần mềm ở bậc cao hơn
• Những đối tượng trong một ngôn ngữ OOP là các kết hợp giữa mã
và dữ liệu mà chúng được nhìn nhận như là một đơn vị duy nhất.
• Mỗi đối tượng có một tên riêng biệt và tất cả các tham chiếu đến đối tượng đó được tiến hành qua tên của nó Như vậy, mỗi đối tượng
có khả năng nhận vào các thông báo, xử lý dữ liệu (bên trong của nó), và gửi ra hay trả lời đến các đối tượng khác hay đến môi
trường.
Lập trình hướng đối tượng
(OOP - object-oriented programming)
Trang 3Đối tượng (Object)
• Đối tượng: Các dữ liệu và chỉ thị được kết hợp vào một đơn vị đầy đủ tạo nên
một đối tượng Đơn vị này tương đương với một chương trình con và vì thế các
đối tượng sẽ được chia thành hai bộ phận chính: phần các phương thức
(method) và phần các thuộc tính (property)
• Trong thực tế, các phương thức của đối tượng là các hàm và các thuộc tính
của nó là các biến, các tham số hay hằng nội tại của một đối tượng (hay nói cách khác tập hợp các dữ liệu nội tại tạo thành thuộc tính của đối tượng)
• Các phương thức là phương tiện để sử dụng một đối tượng trong khi các
thuộc tính sẽ mô tả đối tượng có những tính chất gì.
•
Các phương thức và các thuộc tính thường gắn chặt với thực tế các đặc tính và
sử dụng của một đối tượng
• Mỗi phương thức hay mỗi dữ liệu nội tại cùng với các tính chất được định
nghĩa (bởi người lập trình) được xem là một đặc tính riêng của đối tượng
Trang 43.1 Các tính chất cơ bản
Tính trừu tượng (abstraction):
Là khả năng của chương trình bỏ qua hay không chú ý đến một số khía cạnh của thông tin mà nó đang trực tiếp thực hiện, nghĩa là nó có khả năng tập trung vào những cốt lõi cần thiết
Mỗi đối tượng có thể hoàn tất các công việc một cách nội bộ, liên lạc với các đối tượng khác mà không cần cho biết làm cách nào đối tượng tiến hành
được các thao tác Tính chất này thường được gọi là sự trừu tượng của dữ
liệu.
Tính trừu tượng còn thể hiện qua việc một đối tượng ban đầu có thể có một
số đặc điểm chung cho nhiều đối tượng khác như là sự mở rộng của nó
Tính trừu tượng này thường được xác định trong khái niệm gọi là lớp trừu
tượng hay lớp cơ sở trừu tượng.
Trang 5Tính đóng gói (encapsulation) và che dấu thông tin (information hiding):
Tính chất này không cho phép người sử dụng các đối tượng thay đổi
trạng thái nội tại của một đối tượng
Chỉ có các phương thức nội tại của đối tượng cho phép thay đổi trạng thái của nó
Việc cho phép môi trường bên ngoài tác động lên các dữ liệu nội tại của một đối tượng theo cách nào đó là hoàn toàn tùy thuộc vào người viết mã Đây là tính chất đảm bảo sự toàn vẹn của đối tượng
Trang 6Tính đa hình (polymorphism):
Thể hiện thông qua việc gửi các thông điệp (message) Việc gửi các thông
điệp này có thể so sánh như việc gọi các hàm bên trong của một đối tượng
Các phương thức dùng trả lời cho một thông điệp sẽ tùy theo đối tượng mà thông điệp đó được gửi tới sẽ có phản ứng khác nhau
Người lập trình có thể định nghĩa một đặc tính (chẳng hạn thông qua tên của các phương thức) cho một loạt các đối tượng gần nhau nhưng khi thi hành thì dùng cùng một tên gọi mà sự thi hành của mỗi đối tượng sẽ tự
động xảy ra tương ứng theo đặc tính của từng đối tượng mà không bị nhầm lẫn
Thí dụ khi định nghĩa hai đối tượng "hinh_vuong" và "hinh_tron" thì có một phương thức chung là "chu_vi" Khi gọi phương thức này thì nếu đối tượng
là "hinh_vuong" nó sẽ tính theo công thức khác với khi đối tượng là
"hinh_tron".
Trang 7Tính kế thừa (inheritance):
Đặc tính này cho phép một đối tượng có thể có sẵn các đặc tính mà đối tượng khác đã có thông qua kế thừa
Điều này cho phép các đối tượng chia sẻ hay mở rộng các đặc tính sẵn có
mà không phải tiến hành định nghĩa lại
Trang 83.2 Một số khái niệm
Lớp (class)
• Một lớp có thể được hiểu là khuôn mẫu để tạo ra các đối tượng
Trong một lớp, người ta thường dùng các biến để mô tả các thuộc tính và các hàm để mô tả các phương thức của đối tượng
• Khi đã định nghĩa được lớp, ta có thể tạo ra các đối tượng từ lớp này Để việc sử dụng được dễ dàng, thông qua hệ thống hàm tạo (constructor), người ta dùng lớp như một kiểu dữ liệu để tạo ra các đối tượng.
Trang 9Lớp trừu tượng hay lớp cơ sở trừu tượng (abstract class)
• Lớp trừu tượng là một lớp mà nó không thể thực thể hóa thành một đối
tượng thực dụng được Lớp này được thiết kế nhằm tạo ra một lớp có các đặc tính tổng quát nhưng bản thân lớp đó chưa có ý nghĩa (hay không đủ ý nghĩa) để có thể tiến hành viết mã cho việc thực thể hóa
• Thí dụ: Lớp "hinh_thang" được định nghĩa không có dữ liệu nội tại và chỉ có các phương thức (hàm nội tại) "tinh_chu_vi", "tinh_dien_tich" Nhưng vì lớp hinh_thang này chưa xác định được đầy đủ các đặc tính của nó (cụ thể các biến nội tại là tọa độ các đỉnh nếu là đa giác, là đường bán kính và toạ độ tâm nếu là hình tròn, ) nên nó chỉ có thể được viết thành một lớp trừu
tượng Sau đó, người lập trình có thể tạo ra các lớp con chẳng hạn như là lớp "tam_giac", lớp "hinh_tron", lớp "tu_giac", Và trong các lớp con này người viết mã sẽ cung cấp các dữ liệu nội tại (như là biến nội tại r làm bán kính và hằng số nội tại Pi cho lớp "hinh_tron" và sau đó viết mã cụ thể cho các phương thức "tinh_chu_vi" và "tinh_dien_tich")
Trang 10• Mỗi phương thức thường được định nghĩa là một hàm, các thao tác
để thực hiện hành vi đó được viết tại nội dung của hàm
• Một số loại phương thức đặc biệt:
Hàm tạo (constructor) là hàm được dùng để tạo ra một đối tượng,
cài đặt các giá trị ban đầu cho các thuộc tính của đối tượng đó
Hàm hủy (destructor) là hàm dùng vào việc làm sạch bộ nhớ đã
dùng để lưu đối tượng và hủy bỏ tên của một đối tượng sau khi đã
Trang 11• Các thuộc tính có thể được xác định kiểu và kiểu của chúng có thể
là các kiểu dữ liệu cổ điển hay đó là một lớp đã định nghĩa từ
trước
Quan hệ giữa lớp và đối tượng
• Lớp trong là cách phân loại các thực thể dựa trên những đặc điểm chung của các thực thể đó Do đó lớp là khái niệm mang tính trừu tượng hóa rất cao
• Một đối tượng là thực thể hóa (instantiate) của một lớp đã được định nghĩa.
Trang 12• Công cộng (public)
Là một tính chất được dùng để gán cho các phương thức, các biến nội tại,
hay các lớp mà khi khai báo thì người lập trình đã cho phép các câu lệnh bên ngoài cũng như các đối tượng khác được phép dùng đến nó
• Riêng tư (private)
Là sự thể hiện tính chất đóng mạnh nhất (của một đặc tính hay một lớp) Khi dùng tính chất này gán cho một biến, một phương pháp thì biến hay phương pháp đó chỉ có thể được sử dụng bên trong của lớp mà chúng được định nghĩa
• Bảo vệ (protected)
Chỉ có trong nội bộ của lớp đó hay các lớp có quan hệ đặc biệt mới được phép gọi đến hay dùng đến các thành phần được bảo vệ Có sự khác nhau trong các ngôn ngữ lập trình
• Đa kế thừa (multiple inheritance)
Một lớp con có khả năng kế thừa trực tiếp cùng lúc nhiều lớp khác.
Trang 133.3 Các nguyên lý thiết kế
hướng đối tượng
1 Xác định lớp đối tượng
• Đặt câu hỏi "Ta đang nói về cái gì" chứ chưa đặt vấn đề "Ta muốn làm
gì", nghĩa là hướng đến đối tuợng trước Để xác định đối tượng cần phải xác dịnh lớp các đối tượng
• Việc xem xét lớp đối tượng đáng quan tâm có thể dựa trên nguyên lý
sau:
Nếu ta nói về vấn đề nào đó bằng cách quy cho nó các tính chất hay
nếu phải thao tác trên các vấn đề này thì cần phải xác định lớp đối tượng cho nó.
Trang 14trong phần mềm đang tạo ra.
Trang 154 Các bước trong thiết kế hướng đối tượng:
(1) Xác định thực thể trong miền:
Làm thế nào để xác định chính xác lớp đối tượng Có các cánh sau:
C1: Xem xét một lõi nhỏ các lớp ban đầu được coi là "hiễn nhiên", rồi trong quá trình thực hiện, có thể thêm vào các lớp mới bằng cách gộp nhón các lớp hiện có
C2: Vét cạn tất cả, trong quá trinh thực hiện sẽ lọai bỏ dần
C3: Gộp nhóm các tính chất và các quan hệ mà chưa rút ra ngay các lớp Sau đó phân lọai các tính chất và từ đó xác định đối tượng
(2) Cấu trúc miền thông qua việc phân tích các tính chất và quan hệ:
Khi đã định xong các lớp, cần phải biết cách tổ chức và liên kết chúng lại
(3) Xác định các thao tác:
Đầu tiên các định các thao tác mà các dối tượng cần thíết phải có sau đó mới nâng dần lên ở dạng trừu tượng hơn Chẳng hạn có thể có thể năng thao tác của một đối tượng X lên cho lớp cơ sở được nó kế thừa và có thể lớp cơ sở thao tác này là "không làm gì cả"
(4) Mô tả chính xác các thao tác:
(5) Cho phép thực hiện
Trang 163.4 Hạn chế của phương pháp
lập trình OOP
• OOP mô phỏng đối tượng trong thế giới thực (sinh - họat động - tử ) nhưng không thể làm cho đối tượng tiến hóa Nếu OOP đưa vào các dự đoán
trước cho yêu cầu tiến triển thì phần mềm sẽ nặng nề
• Thực tế, một hệ thống là sự đan xen nhau giữa các yêu cầu Giả sử cần phải thêm một yêu cầu mới cho một object, OOP buộc phải bổ sung thêm code cho object đó Điều này dẫn đến sự chồng chéo giữa các yêu cầu và làm cho hệ thống trở nên lộn xộn, khó bảo trì, phát triển Khi bổ sung thêm một yêu cầu, OOP buộc phải thay đổi các yêu cầu về nghiệp vụ liên quan
Trang 173.6 Nhìn qua về OOP trong C++
• public: các thành phần được truy
xuất từ bất kỳ ở đâu đối tượng hiển diện
Lưu ý: Khia báo private có thể không cần
Trang 18Ví dụ: #include <iostream>
using namespace std;
class CRectangle { int x, y;
public:
void set_values (int,int);
int area () {return (x*y);}
rect.set_values (3,4);
rectb.set_values (5,6);
cout << "rect area: " << rect.area() << endl;
Trang 19CRectangle rectb (5,6);
cout << "rect area: " << rect.area() << endl; cout << "rectb area: " << rectb.area() << endl; return 0;
}
Trang 20CRectangle rectb;
cout << "rect area: " << rect.area() << endl; cout << "rectb area: " << rectb.area() << endl; return 0;
}
Lưu ý:
CRectangle rectb; // đúng CRectangle rectb(); // sai
Trang 21Khi đó, có thể khai báo: CExample ex;
• Nếu có khai báo cấu tử:
class CExample {
public: int a,b,c;
CExample (int n, int m) { a=n; b=m; };
void multiply () { c=a*b; };
Trang 22• Cấu tử copy:
Nếu khai báo một cấu tử là:
CExample::CExample (const CExample& rv)
Trang 23CRectangle::CRectangle (int a, int b) {
width = new int;
height = new int;
*width = a;
*height = b;
}
CRectangle::~CRectangle () { delete width;
delete height;
}
int main () { CRectangle rect (3,4), rectb (5,6);
cout << "rect area: " << rect.area() << endl; cout << "rectb area: " << rectb.area() << endl; return 0;
}
Trang 24void set_values (int, int);
int area (void) {return (width * height);}
};
void CRectangle::set_values (int a, int b) {
width = a;
int main () { CRectangle a, *b, *c;
CRectangle * d = new CRectangle[2];
cout << "a area: " << a.area() << endl;
cout << "*b area: " << b->area() << endl; cout << "*c area: " << c->area() << endl; cout << "d[0] area: " << d[0].area() << endl; cout << "d[1] area: " << d[1].area() << endl; delete[] d;
Trang 25• Lưu ý cách viết:
Biểu thức Có thể hiểu
&x Điạ chỉ của x
x->y Thành phần y của đối tượng được trỏ bởi x
(*x).y Thành phần y của đối tượng được trỏ bở x (như trên)
x[0] Đối tượng đầu tiên được trỏ bởi x
x[1] Đối tượng thứ hai được trỏ bởi x
x[n] Đối tượng thứ (n+1) được trỏ bởi x
Trang 26Các toán tử overloading
Có thể sử dụng cú pháp sau để tạo ra các toán tử overloading:
type operator sign (parameters)
Trang 28int isitme (CDummy& param);
};
int CDummy::isitme (CDummy& param) {
if (¶m == this) return true;
else return false;
}
int main () { CDummy a;
CDummy* b = &a;
if ( b->isitme(a) ) cout << "yes, &a is b";
return 0;
}
Trang 29CDummy * c = new CDummy;
cout << a.n << endl;
Trang 31void set_values (int, int);
int area () {return (width * height);}
friend CRectangle duplicate (CRectangle);
rectres width = rectparam width *2;
rectres height = rectparam height *2;
return (rectres);
}
int main () { CRectangle rect, rectb;
rect.set_values (2,3);
rectb = duplicate (rect);
cout << rectb.area();
return 0;
Trang 32{return (width * height);}
void convert (CSquare a);
void set_side (int a)
void CRectangle::convert (CSquare a) {
width = a.side; height = a.side;}
int main () { CSquare sqr;
Trang 33Kế thừa (Inheritance) giữa các lớp
Cú pháp khai báo lớp kế thừa:
class derived_class_name: public base_class_name
Các thành phần cùng lớp Được Được Được
Các thành phần của lớp dẫn xuất Được Được Không
Không phải là thành phần thuộc lớp
Nhắc lại tính chất của các thành phần trong class:
public: Các thành phần kế thừa được “đưa vào” vùng public của lớp dẫn xuất
protected: Các thành phần kế thừa được “đưa vào” vùng protected của lớp dẫn xuất
private: Các thành phần kế thừa được “đưa vào” vùng private của lớp dẫn xuất
Trang 35Những gì được kế thừa từ lớp cơ sở?
• Một lớp dẫn xuất kế thừa các thành phần của lớp cơ sở, trừ các thành phần sau:
– Các cấu tử và huỹ tử của nó
– Toán tử operator=()
– Các friend
• Mặc dù các cấu tử và hũy tử của lớp cơ sở không được kế thừa nhưng cấu
tử mặc định (tức cấu tử không tham số), hũy tử mặc định sẽ luôn luôn được gọi khi một đối tượng của lớp dẫn xuất được tạo hoặc bị hũy bỏ
• Nếu lớp cơ sở không định nghĩa cấu tử mặc định hoặc muốn một cấu tử overload được gọi khi một đối tượng của lớp dẫn xuất được tạo thì có thể chỉ ra nó trong mỗi cấu tử của lớp dẫn xuất theo cú pháp:
derived_constr_name ( parameters ) : base_constr_name ( parameters )
{
.
}
Trang 36contrai (int a) : me (a)
{ cout << “contrai: có tham số\n\n"; }
};
int main () { congai g (0);
Trang 37Kế thừa bội (Multiple inheritance)
• Một lớp dẫn xuất có thể được kế thừa từ nhiều lớp cơ sở
• Các cấu tử và hũy tử của lớp dẫn xuất cũng có thể thiết lập tương tự như trên
class CTriangle: public CPolygon, public COutput { public:
int area () { return (width * height / 2); } };
int main () { CRectangle rect;
Trang 38Đa hình (Polymorphism)
• Chúng ta nhớ rằng
int a::b(int c) { } Các lớp
class a: public b { }; Friend và inheritance
Trang 39cout << r.area() << endl;
cout << t.area() << endl;
Trang 40Các thành phần ảo (Virtual members)
Một thành phần mà nó có thể phải được định nghĩa lại trong lớp dẫn xuất được hiểu
như là thành phần ảo Để tạo ra thành phần ảo như vậy, ta sử dụng từ khoá virtual.
cout << p1->area() << endl;
cout << p2->area() << endl;
cout << p3->area() << endl;
return 0;
}
20100
Nhận xét: Các tham chiếu của p1,p2,p3 đến CRectangle::area(),
CTriangle::area() và CPolygon::area()