Giáo trình Lập trình hướng đối tượng

Chương 1 trình bày những vấn đề sau:

ỉ Thảo luận về cách tiếp cận hướng đối tượng, những nhược điểm của lập trình truyền thống và các đặc điểm của lập trình hướng đối tượng.

ỉ Các khái niệm cơ sở của phương pháp hướng đối tượng:

ã Đối tượng

ã Lớp

ã Trừu tượng hóa dữ liệu và bao gói thông tin

ã Kế thừa

ã Tương ứng bội

ã Liên kết động

ã Truyền thông báo

ỉ Các bước cần thiết để thiết kế chương trình theo hướng đối tượng

ỉ Các ưu điểm của lập trình hướng đối tượng

ỉ Các ngôn ngữ hướng đối tượng

ỉ Một số ứng dụng của lập trình hướng đối tượng

1.1. Giới thiệu

1.1.1. Tiếp cận hướng đối tượng

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 kinh doanh được xem như những đối tượng. Các phòng ở đây có thể là: phòng quản lý, phòng bán hàng, phòng kế toán, phòng tiếp thị,. Mỗi phòng ngoài những cán bộ đảm nhiệm những công việc cụ thể, còn có những dữ liệu riêng như thông tin về nhân viên, doanh số bán hàng, hoặc các dữ liệu khác có liên quan đến bộ phận đó. Việc phân chia các phòng chức năng trong công ty sẽ tạo điều kiện dễ dàng cho việc quản lý các hoạt động. Mỗi nhân viên trong phòng sẽ điều khiển và xử lý dữ liệu của phòng đó. Ví dụ phòng kế toán phụ trách về lương bổng nhân viên trong công ty. Nếu bạn đang ở bộ phận tiếp thị và cần tìm thông tin chi tiết về lương của đơn vị mình thì sẽ gởi yêu cầu về phòng kế toán. Với cách làm này bạn được đảm bảo là chỉ có nhân viên của bộ phận kế toán được quyền truy cập dữ liệu và cung cấp thông tin cho bạn. Điều này cũng cho thấy rằng, không có người nào thuộc bộ phận khác có thể truy cập và thay đổi dữ liệu của bộ phận kế toán. Khái niệm như thế về đối tượng hầu như có thể được mở rộng đối với mọi lĩnh vực trong đời sống xã hội và hơn nữa - đối với việc tổ chức chương trình. Mọi ứng dụng có thể được định nghĩa như một tập các thực thể - hoặc các đối tượng, sao cho quá trình tái tạo những suy nghĩa của chúng ta là gần sát nhất về thế giới thực.

Trong phần tiếp theo chúng ta sẽ xem xét phương pháp lập trình truyền thống để từ đó thấy rằng vì sao chúng ta cần chuyển sang phương pháp lập trình hướng đối tượng.

1.1.2. Những nhược điểm của lập trình hướng thủ tục

Cách tiếp cận lập trình truyền thống là lập trình hướng thủ tục (LTHTT). Theo cách tiếp cận này thì một hệ thống phần mềm được xem như là dãy các công việc cần thực hiện như đọc dữ liệu, tính toán, xử lý, lập báo cáo và in ấn kết quả v.v. Mỗi công việc đó sẽ được thực hiện bởi một số hàm nhất định. Như vậy trọng tâm của cách tiếp cận này là các hàm chức năng. LTHTT sử dụng kỹ thuật phân rã hàm chức năng theo cách tiếp cận trên xuống (top-down) để tạo ra cấu trúc phân cấp. Các ngôn ngữ lập trình bậc cao như COBOL, FORTRAN, PASCAL, C, v.v., là những ngôn ngữ lập trình hướng thủ tục. Những nhược điểm chính của LTHTT là:

ỉ Chương trình khó kiểm soát và khó khăn trong việc bổ sung, nâng cấp chương trình. Chương trình được xây dựng theo cách TCHTT thực chất là danh sách các câu lệnh mà theo đó máy tính cần thực hiện. Danh sách các lệnh đó được tổ chức thành từng nhóm theo đơn vị cấu trúc của ngôn ngữ lập trình và được gọi là hàm/thủ tục. Trong chương trình có nhiều hàm/thủ tục, thường thì có nhiều thành phần dữ liệu quan trọng sẽ được khai báo tổng thể (global) để các hàm/thủ tục có thể truy nhập, đọc và làm thay đổi giá trị của biến tổng thể. Điều này sẽ làm cho chương trình rất khó kiểm soát, nhất là đối với các chương trình lớn, phức tạp thì vấn đề càng trở nên khó khăn hơn. Khi ta muốn thay đổi, bổ sung cấu trúc dữ liệu dùng chung cho một số hàm/thủ tục thì phải thay đổi hầu như tất cả các hàm/thủ tục liên quan đến dữ liệu đó.

ỉ Mô hình được xây dựng theo cách tiếp cận hướng thủ tục không mô tả được đầy đủ, trung thực hệ thống trong thực tế.

ỉ Phương pháp TCHTT đặt trọng tâm vào hàm là hướng tới hoạt động sẽ không thực sự tương ứng với các thực thể trong hệ thống của thế giới thực.

 

doc156 trang | Chia sẻ: hienduc166 | Lượt xem: 756 | Lượt tải: 0download
Bạn đang xem trước 20 trang tài liệu Giáo trình Lập trình hướng đối tượng, để xem tài liệu hoàn chỉnh bạn click vào nút TẢI VỀ ở trên
ios::internal
 Cờ ios::left: khi bật cờ ios::left thì giá trị in ra nằm bên trái vùng quy định, các ký tự độn nằm sau.
 Cờ ios::right: khi bật cờ ios::right thì giá trị in ra nằm bên phải vùng quy định, các ký tự độn nằm trước.
 Chú: ý mặc định cờ ios::right bật.
 Cờ ios::internal: cờ ios::internal có tác dụng giống như cờ ios::right chỉ khác là dấu (nếu có) in đầu tiên.
 Chương trình sau minh hoạ cách dùng các cờ căn lề:
Ví dụ 
#include 
#include 
void main()
 {
 clrscr();
 float x=-87.1551, y=23.45421;
 cout.precision(2);
 cout.fill('*');
 cout.setf(ios::left); //bat co ios::left
 cout<<"\n";
 cout.width(8);
 cout<<x;
 cout<<"\n";
 cout.width(8);
 cout<<y;
 cout.setf(ios::right); //bat co ios::right
 cout<<"\n";
 cout.width(8);
 cout<<x;
 cout<<"\n";
 cout.width(8);
 cout<<y;
 cout.setf(ios::internal); //bat co ios::internal
 cout<<"\n";
 cout.width(8);
 cout<<x;
 cout<<"\n";
 cout.width(8);
 cout<<y;
 getch();
 }
 Sau khi thực hiện chương trình in ra 6 dòng như sau:
 -87.16**
 23.45**
 **-87.16
 ***23.45
 -**87.16
 ***23.45
 Nhóm 2 gồm các cờ định dạng số nguyên:
 ios::dec ios::oct ios::hex
 + Khi ios::dec bật (mặc định): số nguyên được in dưới dạng cơ số 10
 + Khi ios::oct bật: số nguyên được in dưới dạng cơ số 8
 + khi ios::hex bật: số nguyên được in dưới dạng cơ số 16
 Nhóm 3 gồm các cờ định dạng số thực:
 	ios::fixed ios::scientific ios::showpoint 
 Mặc định : cờ ios::fixed bật (on) và cờ ios::showpoint tắt (off).
 + Khi ios::fixed bật và cờ ios::showpoint tắt thì số thực in ra dưới dạng thập phân, số chữ số phần phân (sau dấu chấm) được tính bằng độ chính xác n nhưng khi in thì bỏ đi các chữ số 0 ở cuối.
 Ví dụ nếu độ chính xác n = 4 thì
 Số thực -87.1500 được in: -87.15
 Số thực 23.45425 được in: 23.4543
 Số thực 678.0 được in: 678
 + Khi ios::fixed bật và cờ ios::showpoint bật thì số thực in ra dưới dạng thập phân, số chữ số phần phân (sau dấu chấm) được in ra đúng bằng độ chính xác n. 
 Ví dụ nếu độ chính xác n = 4 thì
 Số thực -87.1500 được in: -87.1500
 Số thực 23.45425 được in: 23.4543
 Số thực 678.0 được in: 6780000
 + Khi ios::scientific bật và cờ ios::showpoint tắt thì số thực in ra dưới dạng khoa học. Số chữ số phần phân (sau dấu chấm) được tính bằng độ chính xác n nhưng khi in thì bỏ đi các chữ số 0 ở cuối.
 Ví dụ nếu độ chính xác n=4 thì
 Số thực -87.1500 được in: -87.15e+01
 Số thực 23.45425 được in: 23.4543e+01
 Số thực 678.0 được in: 678e+02
 + Khi ios::scientific bật và cờ ios::showpoint bật thì số thực in ra dưới dạng mũ . Số chữ số phần phân (sau dấu chấm) của phần định trị được in đúng bằng độ chính xác n.
 Ví dụ nếu độ chính xác n=4 thì
 Số thực -87.1500 được in: -87.150e+01
 Số thực 23.45425 được in: 23.4543e+01
 Số thực 678.0 được in: 67800e+01
 Nhóm 4 gồm các hiển thị:
 ios::uppercase ios::showpos ios::showbase
 Cờ ios::showpos
 + Nếu cờ ios::showpos tắt (mặc định) thì dấu cộng không được in trước số dương.
 + Nếu cờ ios::showpos tắt thì dấu cộng được in trước số dương.
 Cờ ios::showbase bật thì số nguyên hệ 8 được in bắt đầu bằng ký tự 0 và số nguyên hệ 16 được bắt đầu bằng các ký tự 0x. Ví dụ nếu a = 40 thì:
 Dạng in hệ 8 là: 050
 Dạng in hệ 16 là 0x28
 Cờ ios::showbase tắt (mặc định) thì không in 0 trước số nguyên hệ 8 và không 0x trước số nguyên hệ 16. Ví dụ nếu a = 40 thì:
 Dạng in hệ 8 là: 50
 Dạng in hệ 16 là 28
 Cờ ios::uppercase
 + Nếu cờ ios::uppercase bật thì các chữ số hệ 16 (như A, B, C,...) được in dưới dạng chữ hoa.
 + Nếu cờ ios::uppercase tắt (mặc định) thì các chữ số hệ 16 (như A, B, C,...) được in dưới dạng chữ thường.
1.4.5. Các phương thức bật tắt cờ
 Các phương thức này định nghĩa trong lớp ios.
1. Phương thức long cout.setf(long f) ;
sẽ bật các cờ liệt kê trong f và trả về một giá trị long biểu thị các cờ đang bật. 
2. Phương thức long cout.unsetf(long f) ;
 sẽ tắt các cờ liệt kê trong f và trả về một giá trị long biểu thị các cờ đang bật. 
3. Phương thức long cout.flags(long f) ;
có tác dụng giống như cout.setf(long). 
4. Phương thức long cout.flags() ;
sẽ trả về một giá trị long biểu thị các cờ đang bật.
1.4.6. Các bộ phận định dạng 
 Các bộ phận định dạng (định nghĩa trong tập tin iostream.h) bao gồm:
 dec // như cờ ios::dec
 oct // như cờ ios::oct
 hex // như cờ ios::hex
 endl // xuất ký tự ‘\n’ (chuyển dòng)
 flush // đẩy dữ liệu ra thiết bị xuất 
Ví dụ Xét chương trình sau:
#include 
#include 
#include 
void main()
 {
 clrscr();
 cout.setf(ios::showbase);
 cout<<”ABC”<<endl<<hex<<40<<” ”<<41;
 getch();
 }
1.4.7. Các hàm định dạng 
 Các hàm định dạng (định nghĩa trong ) bao gồm:
 set(int n) // như cout.width(int n)
 setpecision(int n) // như cout.setpecision(int n)
 setfill( char ch) // như cout.setfill( char ch)
 setiosflags( long l) // như cout. setiosflags( long f)
 resetiosflags( long l) // như cout. setiosflags( long f)
Các hàm định dạng có tác dụng như các phương thức định dạng nhưng được viết nối đuôi trong toán tử xuất nên tiện sử dụng hơn.
 Chú ý 
Các hàm định dạng ( cũng như các bộ phận định dạng ) cần viết trong toán tử xuất. Một hàm định dạng đứng một mình như một câu lệnh sẽ không có tác dụng dịnh dạng.
Muốn sử dụng các hàm định dạng cần bổ sung vào đầu chương trình câu lệnh: #include 
Chương trình trong ví dụ 1.2. có thể viết lại theo các phương án sau:
Phương án 1:
#include 
#include 
void main()
 {
 clrscr();
 cout <<setiosflags(ios::showbase);
 cout<<”ABC”<<endl<<hex<<40<<” “<<41;
 getch();
 }
 Phương án 2:
#include 
#include 
void main()
 {
 clrscr();
 cout <<”ABC”<<endl<< setiosflags(ios::showbase)
 << hex<<40<<” “<<41;
 getch();
 }
1.5. Các dòng chuẩn
 Có 4 dòng (đối tượng của các lớp stream) đã định nghĩa trước, được cài đặt khi chương trình khởi động là:
 	- cin dòng input chuẩn gắn với bàn phím, giống như stdin của C.
- cout dòng output chuẩn gắn với màn hình, giống như stdout của C.
- cerr dòng output lỗichuẩn gắn với màn hình, giống như stderr của C.
- clog giống cerr nhưng có thêm bộ đệm.
 Chú ý 
Có thể dùng các dòng cerr và clog để xuất ra màn hình như đã dùng đối với cout.
Vì clog có thêm bộ đệm, nên dữ liệu được đưa vào bộ đệm. Khi đầy bộ đệm thì đưa dữ liệu bộ đệm ra dòng clog. Vì vậy trước khi kết thúc xuất cần dùng phương thức: clog.flush(); để đẩy dữ liệu từ bộ đệm ra clog.
Chương trình sau minh họa cách dùng dòng clog. Chúng ta nhận thấy, nếu bỏ câu lệnh clog.flush() thì sẽ không nhìn thấy kết quả xuất ra màn hình khi chương trình tạm dừng bởi câu lệnh getch().
Ví dụ
#include 
#include 
void main()
 {
 clrscr();
 float x=-87.1500, y=23.45425,z=678.0;
 clog.setf(ios::scientific);
 clog.precision(4);
 clog.fill('*');
 clog<<"\n";
 clog.width(10);
 clog<<x;
 clog<<"\n";
 clog.width(10);
 clog<<y;
 clog<<"\n";
 clog.width(10);
 clog<<z;
 clog.flush();
 getch();
 }
1.6. Xuất ra máy in 
Bốn dòng chuẩn không gắn với máy in. Như vậy không thể dùng các dòng này để xuất dữ liệu ra máy in. Để xuất dữ liệu ra máy in (cũng như nhập, xuất trên tệp) cần tạo ra các dòng tin mới và cho nó gắn với thiết bị cụ thể. C++ cung cấp 3 lớp stream để làm điều này, đó là các lớp:
	ofstream dùng để tạo các dòng xuất (ghi tệp)
	ifstream dùng để tạo các dòng nhập (độc tệp)
	fstream dùng để tạo các dòng nhập, dòng xuất hoặc dòng nhập-xuất
Mỗi lớp có 4 hàm tạo dùng để khai báo các dòng (đối tượng dòng tin). Để tạo một dòng xuất và gắn nó với máy in ta có thể dùng một trong những hàm tạo sau đây:
	ofstream Tên_dòng(int fd);
	ofstream Tên_dòng(int fd, chả *buf, int n);
Trong đó:
	- Tên_dòng là tên biến đối tượng kiểu ofstream chúng ta tự đặt.
	- fd(file disciptor) là chỉ số tập tin. Chỉ số tập tin định sẵn đối với stdprn (máy in chuẩn) là 4.
	- Các tham số buf và n xác định một vùng nhớ n byte do buff trỏ tới. Vùng nhớ sẽ được làm bộ đệm cho dòng xuất.
Ví dụ: Câu lệnh ofstream prn(4); sẽ tạo dòng tin xuất prn và gắn nó với máy in chuẩn. Dòng prn sẽ có bộ đệm mặc định. Dữ liệu trước hết chuyển vào bộ đệm, khi đầy bộ đêm thì dữ liệu sẽ được đẩy từ bộ đệm ra dòng prn và có thể sử dụng phương thức flush hoặc bộ phận định dạng flush. Cách viết như sau:
	prn.flush ;// Phương thức
	prn<<flush; //Bộ phận định dạng
Các câu lệnh sau sẽ xuất dữ liệu ra prn (máy in) và ý nghĩa của chúng như sau:
	prn<<”\n Tong=”<<(4+9); //Đưa một dòng vào bộ đệm
	prn<<”\n Tich=”<<(4*9); // Đưa dòng tiếp theo vào bộ đệm 
	prn.flush(); //Đẩy dữ liệu từ bộ đệm ra máy in (in 2 dòng)
Các câu lệnh dưới đây sẽ xuất dữ liệu ra máy in nhưng xuất từng dòng một:
	prn<<”\n Tong=”<<(4+9)<<flush; // In một dòng
	prn<<”\n Tích=”<<(4*9)<<flush; //In dòng tiếp theo
Ví dụ: Các câu lệnh
	char buf [512];
	ofstream prn(4,buf,512);
sẽ tạo dòng tin xuất prn và gắn nó với máy in chuẩn. Dòng xuất prn sử dụng 512 byte của mảng buf làm bộ đệm. Các câu lệnh dưới đây cũng xuất ra máy in:
	prn<<”\n Tong=”<<(4+9); //Đưa dữ liệu vào bộ đêm
 	prn<<”\n Tich=”<<(4*9) ; //Đưa dữ liệu vào bộ đêm
	prn.flush(); // Xuất 2 dòng (ở bộ đệm) ra máy in
Chú ý: Trước khi kết thúc chương trình, dữ liệu từ bộ đệm sẽ được tự động đẩy ra máy in.
tài liệu tham khảo
1. Ivar Jacobson, Object - Oriented Software Engineering, Addison-Wesley Publishing Company, 1992.
2. Michael Blaha, William Premerlani, Object - Oriented Modeling and Design for Database Applications, Prentice Hall, 1998.
2. Phạm Văn ất, C++ và Lập trình hướng đối tượng, NXB Khoa học và Kỹ thuật, 1999.
3. Đoàn Văn Ban, Phân tích và thiết kế hướng đối tượng, NXB Khoa học và Kỹ thuật, 1997.
4. Nguyễn Thanh Thủy, Lập trình hướng đối tượng với C++, NXB Khoa học và Kỹ thuật, 1999.
Mục lục
CHươNG 1
CáC KHáI NIệM Cơ Sở
của LậP TRìNH HướNG ĐốI TượNG

File đính kèm:

  • docGiao trinh lap trinh huong doi tuong.doc