Giáo trình Lập trình C++: Từ cơ bản đến nâng cao
Lập trình
Máy tính số là một công cụ để giải quyết hàng loạt các bài toán lớn. Một lời giải cho một
bài toán nào đó được gọi là một giải thuật (algorithm); nó mô tá một chuồi các bước cần
thực hiện đế giải quyết bài toán. Một ví dụ đơn giản cho một bài toán vả một giải thuật có
thể là:
Bài toán: sắp xếp một danh sách các số theo thứ tự tăng dần.
Giải thuật:G iả sử danh sách đã cho là listl; tạo ra một danh sách rỗng, list2,
để lưu danh sách đã sắp xếp. Lặp đi lặp lại công việc, tìm số nhỏ nhất trong
listl, xóa nó khỏi listl, và thêm vào phần tử kế tiếp trong danh sách list2, cho
đến khi lỉstl là rỗng.
Giải thuật được diễn giải bằng các thuật ngữ trừu tượng mang tính chất dề hiểu. Ngôn
ngữ thật sự được hiểu bởi máy tính là ngôn ngữ máy. Chương trình được diễn đạt bằng
ngôn ngữ máy được gọi là có thể thực thi. Một chương trình được viết bằng bất kỳ một
ngôn ngừ nào khác thì trước hết cần được dịch sang ngôn ngữ máy để máy tính có thể
hiếu và thực thi nó.
Ngôn ngữ máy cực kỳ khó hiểu đối với lập trình viên vì thế họ không thể sử dụng
trực tiếp ngôn ngữ máy đế viết chương trình. Một sự trừu tượng khác là ngôn ngữ
assembly. Nó cung cấp những tên dỗ nhớ cho các lệnh và một ký hiệu dễ hiếu hơn cho
dữ liệu. Bộ dịch được gọi là assembler chuyển ngôn ngữ assembly sang ngôn ngừ máy.
Ngay cả những ngôn ngữ assembly cũng khó sử dụng. Những ngôn ngữ cấp cao
như C++ cung cấp các ký hiệu thuận tiện hon nhiều cho việc thi hành các giải thuật.
Chúng giúp cho các lập trình viên không phải nghĩ nhiều về các thuật ngữ cấp thấp, và
giúp họ chỉ tập trung vào giải thuật. T rình biên dịch (compiler) sè đảm nhiệm việc dịch
chương trình viết bằng ngôn ngữ cấp cao sang ngôn ngữ assembly. Mã assembly được
tạo ra bởi trình biên dịch sau đó sẽ được tập hợp lại đế cho ra một chương trình có thể
thực thi.
Tóm tắt nội dung tài liệu: Giáo trình Lập trình C++: Từ cơ bản đến nâng cao
Chương 1. Mở đầu Chương này giói thiệu những phần cơ bản của một chương trình C++. Chúng ta sử dụng những ví dụ đơn giản đế trình bày cấu trúc các chương trình C++ và cách thức biên dịch chúng. Các khái niệm cơ bản như là hằng, biến, và việc lưu trữ chúng trong bộ nhớ cũng sẽ được tháo luận trong chương này. Sau đây là một đặc tả sơ bộ về khái niệm lập trình. Lập trình Máy tính số là một công cụ để giải quyết hàng loạt các bài toán lớn. Một lời giải cho một bài toán nào đó được gọi là một giải thuật (algorithm); nó mô tá một chuồi các bước cần thực hiện đế giải quyết bài toán. Một ví dụ đơn giản cho một bài toán vả một giải thuật có thể là: Bài toán: sắp xếp một danh sách các số theo thứ tự tăng dần. Giải thuật:G iả sử danh sách đã cho là lis tl; tạo ra một danh sách rỗng, list2, để lưu danh sách đã sắp xếp. Lặp đi lặp lại công việc, tìm số nhỏ nhất trong listl, xóa nó khỏi listl, và thêm vào phần tử kế tiếp trong danh sách list2, cho đến khi lỉstl là rỗng. Giải thuật được diễn giải bằng các thuật ngữ trừu tượng mang tính chất dề hiểu. Ngôn ngữ thật sự được hiểu bởi máy tính là ngôn ngữ máy. Chương trình được diễn đạt bằng ngôn ngữ máy được gọi là có thể thực thi. Một chương trình được viết bằng bất kỳ một ngôn ngừ nào khác thì trước hết cần được dịch sang ngôn ngữ máy để máy tính có thể hiếu và thực thi nó. Ngôn ngữ máy cực kỳ khó hiểu đối với lập trình viên vì thế họ không thể sử dụng trực tiếp ngôn ngữ máy đế viết chương trình. Một sự trừu tượng khác là ngôn ngữ assembly. Nó cung cấp những tên dỗ nhớ cho các lệnh và một ký hiệu dễ hiếu hơn cho dữ liệu. Bộ dịch được gọi là assembler chuyển ngôn ngữ assembly sang ngôn ngừ máy. Ngay cả những ngôn ngữ assembly cũng khó sử dụng. Những ngôn ngữ cấp cao như C++ cung cấp các ký hiệu thuận tiện hon nhiều cho việc thi hành các giải thuật. Chúng giúp cho các lập trình viên không phải nghĩ nhiều về các thuật ngữ cấp thấp, và giúp họ chỉ tập trung vào giải thuật. T rình biên dịch (compiler) sè đảm nhiệm việc dịch chương trình viết bằng ngôn ngữ cấp cao sang ngôn ngữ assembly. Mã assembly được tạo ra bởi trình biên dịch sau đó sẽ được tập hợp lại đế cho ra một chương trình có thể thực thi. Chương 1: Mở đầu 1 1.1. Một chưong trình C++ đon giản Danh sách 1.1 trình bày chương trình C++ đầu tiên. Chương trình này khi chạy sẽ xuất ra thông điệp Hello World. Danh sách 1.1 1 2 3 4 5 Chú giải 1 Hàng này sử dụng chỉ thị tiền xử lý #include để chèn vào nội dung của tập tin header iosteam.h trong chương trình, iostrcamli là tập tin header chuẩn của C++ và chứa đựng các định nghĩa cho xuất và nhập. 2 Hàng này định nghĩa một hàm được gọi là main. Hàm có thế không có hay có nhiều tham số (parameters); các tham số này luôn xuất hiện sau tên hàm, giữa một cặp dấu ngoặc. Việc xuất hiện của từ void ở giữa dấu n |oặc chi định rằng hàm main không có tham số. Hàm có thể có kiểu trả về; kiểu trả về luôn xuất hiện trước tên hàm. Kiếu trả về cho hàm main là int (ví dụ: một số nguyên). Tất cả các chương trình C++ phải có một hàm main duy nhất.Việc thực thi chương trình luôn bắt đầu từ hàm main. 3 Dấu ngoặc nhọn bắt đầu thân của hàm mam. 4 Hàng này là một câu lệnh (statement). Một lệnh là một sự tính toán đế cho ra một giá trị. Ket thúc một lệnh thì luôn luôn được đánh dấu bằng dấu chấm phẩy (;). Câu lệnh này xuất ra chuỗi "Hello World®" đế gởi đến dòng xuất cout Chuồi là một dãy các ký tự được đặt trong cặp nháy kép. Ký tự cuối cùng trong chuồi này (\n) là một ký tự xuống hàng (newline). Dòng là một đối tượng được dùng đế thực hiện các xuất hoặc nhập, cout là dòng xuất chuấn trong C++ (xuất chuấn thường được hiểu là màn hình máy tính). Ký tự « là toán tử xuất, nó xem dòng xuất như là toán hạng trái và xem biểu thức như là toán hạng phải, và tạo nên giá trị của biếu thức được gởi đến dòng xuất. Trong trường hợp này, kết quả là chuồi "Hello Worlđ\n" được gởi đến dòng cout, làm cho nó được hiến thị trên màn hình máy tính. 5 Dấu ngoặc đóng kết thúc thân hàm main. 1.2. Biên dịch một chương trình C++ Bảng 1.1 trình bày chương trình trong danh sách 1.1 được biên dịch và chạy trong môi trường UNIX thông thường. Phần in đậm được xem như là đầu vào (input) của người dùng và phần in thường được xem như là đáp ứng của hệ thống. Dấu nhắc ở hàng lệnh UNIX xuất hiện như là ký tự dollar($). #inđude int main (void) { cout« "Hello World'll"; 1_________ ___________ Chương 1: Mở đầu 2 1 2 3 4 Bảng 1.1 Chú giải 1 Lệnh để triệu gọi bộ dịch AT&T của c++ trong môi trường UNIX là cc. Đối số cho lệnh này (hello.cc) là tên của tập tin chứa đựng chương trình. Theo qui định thì tên tập tin có phần mở rộng là .c, .c, hoặc là .cc. (Phần mở rộng này có thể là khác nhau đối với những hệ điều hành khác nhau) 2 Ket quả của sự biên dịch là một tập tin có thế thực thi mặc định là a.out. Đế chạy chương trình, chúng ta sử dụng a.out như là lệnh. 3 Đây là kết quả được cung cấp bởi chương trình. 4 Dấu nhắc ừở về hệ thống chỉ định rằng chương trình đã hoàn tất sự thực thi của nó. Lệnh cc chấp nhận các phần tùy chọn. Mồi tùy chọn xuất hiện như name, trong đó name là tên cùa tùy chọn (thườnệ là một kỷ tự đơn). Một vài tùy chọn yêu cầu có đối số. Ví dụ tùy chọn xuất (-o) cho phép chỉ định rõ tập tin có thế được cung cấp bởi trình biên dịch thay vì là aout. Bảng 1.2 minh họa việc sử dụng tùy chọn này bằng cách chỉ định rõ hello như là tên của tập tin có thể thực thi. Bảng 1.2 1 2 3 4 Mặc dù lệnh thực sự có thế khác phụ thuộc vào trình biên dịch, một thủ tục biên dịch tương tự có thế được dùng dưới môi trường MS-DOS. Trình biên dịch C++ dựa trên Windows dâng tặnẹ một môi trường thân thiện với người dùng mà việc biên dịch rất đơn giản bằng cách chọn lệnh từ menu. Qui định tên dưới MS-DOS và Windows là tên của tập tin nguồn C++ phải có phần mở rộng là .cpp. 1.3. Viêc biên dich C++ diễn ra như thế nào • • Biên dịch một chương trình C++ liên quan đến một số bước (hầu hết các bước là trong suốt với người dùng): • Đầu tiên, bộ tiền xử lý C++ xem qua mã trong chương trình và thực hiện các chỉ thị được chỉ định bởi các chỉ thị tiền xử lý (ví dụ, #include). Ket quả là một mã chương trình đã sửa đối mà không còn chứa bất kỳ một chi thị tiền xử lý nào cả. $ c c heflo.cc -o heDo $ heBo Hello World $ $ c c hello.cc $ a.out Hello World $ Chương 1: Mở đầu 3 • Sau đó, trình biên dịch C++ dịch các mã của chương trình. Trình biên dịch có thế là một trình biên dịch C++ thật sự phát ra mã assembly hay mã máy, hoặc chỉ là trình chuyển đổi dịch mã sang c . Ớ trường họp thứ hai, mã c sau khi được dịch ra sè tạo thành mã assembly hay mã máy thông qua trình biên dịch c . Trong cả hai trường hợp, đầu ra có thể không hoàn chỉnh vì chương trình tham khảo tới các thủ tục trong thư viện còn chưa được định nghĩa như một phần của chương trình. Ví dụ Danh sách 1.1 tham chiếu tới toán tò « mà thực sự được định nghĩa trong một thư viện 10 riêng biệt. • Cuối cùng, trình liên kết hoàn tất mã đối tượng bằng cách liên kết nó với mã đối tượng của bất kỳ các module thư viện mà chương trình đã tham khảo tới. Ket quả cuối cùng là một tập tin thực thi. Hình 1.1 minh họa các bước trên cho cả hai trình chuyến đối C++ và trình biên dịch C++. Thực tế thì tất cả các bước trên được triệu gọi bởi một lệnh đơn (như là CQ và người dùng thậm chí sẽ không thấy các tập tin được phát ra ngay lập tức. Hình 1.1 Việc biên dịch C++ c++ C++ c c Program 17 ► TRANSLATOR ► Code V ► COMPILER C++ Program _J7 ► C++ NATIVE COMPILER 1.4. Biến Biến là một tên tượng trưng cho một vùng nhớ mà dữ liệu có thế được lưu trữ trên đó hay là được sử dụng lại. Các biến được sử dụng đế giữ các giá tri dữ liệu vì thế mà chúng có thế được dùng trong nhiều tính toán khác nhau trong một chương trình. Tất cả các biến có hai thuộc tính quan trọng: • Kiếu được thiết lập khi các biến được định nghĩa (ví dụ như: integer, real, character). Một khi đã được định nghĩa, kiểu của một biến C++ không thể được chuyển đổi. Chương 1: Mở đầu 4 • Giá trị có thể được chuyến đối bằng cách gán một giá trị mới cho biến. Loại giá trị của biến có thể nhận phụ thuộc vào kiểu của nó. Ví dụ, một biến số nguyên chỉ có thể giữ các giá trị nguyên (chắng hạn, 2, 100, -12). Danh sách 1.2 minh họa sử dụng một vài biến đon giản. Danh sách 1.2 2 3 4 5 6 7 8 9 10 11 Chú giải 4 Hàng này định nghĩa một biến int (kiếu số nguyên) tên là workDays, biến này đại diện cho số ngày làm việc trong tuần. Theo như luật chung, trước tiên một biến được định nghĩa bàng cách chi định kiểu của nó, theo sau đó là tên biến và cuối cùng là được kết thúc bởi dấu chấm phấy. 5 Hàng này định nghĩa ba biến float (kiếu số thực) lần lượt thay cho số giờ làm việc trong ngày, số tiền phải trả hàng giờ, và số tiền phải trả hàng tuần. Như chúng ta thấy ở hàng này, nhiều biến của cùng kiếu có thế định nghĩa một lượt qua việc dùng dấu phấy đế ngăn cách chúng. 6 Hàng này là một câu lệnh gán. Nó gán giá trị 5 cho biến workDays. Vì thế, sau khi câu lệnh này được thực thi, workDays biểu thị giá trị 5. 7 Hàng này gán giá ứị 7.5 tới biến workHours. 8 Hàng này gán giá trị 38.55 tới biến payRate. 9 Hàng này tính toán số tiền phải trá hàng tuần từ các biến workDays, workHours, và payRate (* là toán tử nhân). Giá trị kết quả được lưu vào biến weeklyPay. 10-12 Các hàng này xuất ba mục tuần tự là: chuồi "Weekly Pay = ", giá trị của biến weeklyPay, và một ký tự xuống dòng. Khi chạy, chương trình sẽ cho kết quả như sau: Weekly Pay = 1445.625 Khi một biến được định nghĩa, giá trị của nó không được định nghĩa cho đến khi nó được gán cho một giá trị thật sự. Ví dụ, weeklyPay có một giá trị không được định nghĩa cho đến khi hàng 9 được thực thi. Việc gán giá trị cho một biến ở lần đầu tiên được gọi là khỏi tạo. Việc chắc chắn rằng một #mdude int main (void) { int woikDays; float workHoure, payRate, weeklyPay; woikDays=5; workHours _ 7.5; payRate=38.55; weeklyPay=woikDays * workHours * payRate; cout« "Weekly Pay= " « weeklyPay« V; Chương 1: Mở đầu 5 biến được khởi tạo tmớc khi 11Ó được sử dụng trong bất kỳ công việc tính toán nào là rất quan trọng. Một biến có thế được định nghĩa và khởi tạo cùng lúc. Điều này được xem như là một thói quen lập trình tốt bởi vì nó giành trước khả năng sử dụng biến trước khi nó được khởi tạo. Danh sách 1.3 là một phiên bản sửa lại của danh sách 1.2 mà có sử dụng kỹ thuật này. Trong mọi mục đích khác nhau thì hai chương trình là tương tương. Danh sách 1.3 1 2 3 4 56 7 8 9 10 11 1.5. Xuất/nhập đơn giản Cách chung nhất mà một chương trình giao tiếp với thế giới bên ngoài là thông qua các thao tác xuất nhập hướng ký tự đơn giản. C++ cung cấp hai toán tử hữu dụng cho mục đích này là » cho nhập và « cho xuất. Chúng ta đã thấy ví dụ của việc sử dụng toán tử xuất « rồi. Danh sách 1.4 sê minh họa thêm cho việc sử dụng toán tử nhập » . Danh sách 1.4 1 2 3 4 56 7 8 9 10 11 12 13 #inelude int main (void) { int woricDays=5; float workHours=7.5; float payRate,weeklyPay, cout« "What is the hourly pay rate? cin»payRate; weeklyPay=workDays * woricHours * payRate; cout« "Weekly Pay= cout« weeklyPay; cout«W ; #include int main (void) { int woricDays=5; float workHours=7.5; float payRate=38.55; float weeklyPay=woikDays*workHours* payRate; cout« "Weekly Pay="; cout« weeklyPay; cout«\n'; Chương 1: Mở đầu 6 7 Hàng này xuất ra lời nhắc nhở What is the hourly pay rate? để tìm dữ liệu nhập của người dùng. 8 Hàng này đọc giá trị nhập được gõ bởi người dùng và sao chép giá trị này tói biến payRatc. Toán tử nhập » lấy một dòng nhập như là toán hạng trái (cán là dòng nhập chuấn của C++ mà tương ứng với dữ liệu được nhập vào từ bàn phím) và một biến (mà dừ liệu nhập được sao chép tới) như là toán hạng phải. 9-13 Phần còn lại của chương trình là như trước. Khi chạy, chương trình sè xuất ra màn hình như sau (dữ liệu nhập của người dùng được in đậm); What Ls the hourly pay rate? 33.55 Weekly Pay = 1258.125 Cả hai « và » trả về toán hạng trái như là kết quá của chúng, cho phép nhiều thao tác nhập hay nhiều thao tác xuất được kết họp trong một câu lệnh. Điều này được minh họa trong danh sách 1.5 với trường hợp cho phép nhập cả số giờ làm việc mỗi ngày và số tiền phải trả mỗi giờ. Chú giải Danh sách 1.5 2 3 4 5 6 7 8 9 10 Chú giải 7 Hàng này đọc hai giá trị nhập được nliập vào từ người dùng và chép tương ứng chúng tới hai biến workHours và payRale. Hai giá trị cần được tách biệt bởi một không gian trống (chắng hạn, một hay là nhiều khoản trắng hay là các ký tự tab). Câu lệnh này tương đương với: (cin » workHours)» payRale; Vì kết quả của » là toán hạng trái, (cin»workHours) định giá cho cin mà sau đó được sử dụng như là toán hạng trái cho toán tử » kế tiếp. //include int main (void) { int wotfcDays=5; float workHouK, payRate, weeklyPay; cout« "What are the work hours and the hourly pay rate? cin » workHours » payRate; weeklyPay=workDays * workHours * payRate; cout« "Weekly Pay=" « weeklyPay « V; j ______________ ___ _________ _________________ Chương 1: Mở đầu 7 9 Hàng xiày là kết quả của việc kết hợp từ hàng 10 đến hàng 12 trong danli sách 1.4. Nó xuất "Weekly Pay = ", theo sau đó là giá trị của biến weeklyPay, và cuối cùng là một ký tự xuống dòng. Câu lệnh này tương đương với: ((cout« 'Weekly Pay= " ) « weeklyPay)« Vi'; Vì kết quả của « là toán hạng trái, (cout« "Weekly Pay = ") định giá cho cout mà sau đó được sử dụng như là toán hạng trái của toán tử « ké tiếp. Khi chạy, chương trình sẽ hiển thị như sau: What are the work hours and the houriy pay rate? 75 33.55 Weekly Pay = 1258.125 1.6. Chú thích Chú thích thường là một đoạn văn bản. Nó được dùng đế giải thích một vài khía cạnh của chương trình. Trình biên dịch bở qua hoàn toàn các chú thích trong chương trình. Tuy nhiên các chú thích này là có ý nghĩa và đôi khi là rất quan trọng đối với người đọc (người xem các mã chương trình có sẵn) và người phát triển phần mềm. C++ cung cấp hai loại chú thích: • Những gì sau // (cho đến khi kết thúc hàng mà nó xuất hiện) được xem như là một chú thích. • Những gì đóng ngoặc trong cặp dấu ỉ* và */ được xem như là một chú thích. Danh sách 1.6 minh họa việc sử dụng cả hai hình thức này. Danh sách 1.6 2 3 4 5 6 7 8 9 10 11 12 13 Các chú thích nên được sử dụng đế tăng cường (không phải gây trở ngại) việc đọc một chương trình. Một vài điếm sau nên được chú ý: #inđude /* Chuong trinh nay tinh toan tong so tien phai tea hang tuan cho mot cong nhan đua tren tong so gio lam viec va so tien phai tra moi gió. */ int main (void) { int workDays=5; //songay lam viec trongtuan float workHours=7.5; // so gio lam viec trong ngay float payRate=33.50; // so tien phai tra moi gio float weeklyPay, //tong so tien phai tra moi tuan weeklyPay= workDays * workHours * payRate; cout << "Weekly Pay - " « weeklyPay << V; } Chương 1: Mở đầu 8 • Chú thích nên dễ đọc và dỗ hiếu hơn sự giải thícli thông qua mã chương trì ... ơng thức (method) để đặc tả tương ứng cho trạng thái (state) hay biến (variable) và hành động (behavior). Tuy nhiên C++ lại sử dụng hai thuật ngữ dữ liệu thành viên (member data) và hàm thành viên (member function) thay cho các thuật ngữ này. Xét một cách đặc biệt, chỉ một đối tượng riêng rẽ thì chính nó không hữu dụng. Một chương trình hướng đối tượng thường gồm có hai hay nhiều hơn các đối tượng phần mềm tương tác lẫn nhau như là sự tương tác của các đối tượng trong trong thế giới thực. Khái niệm 6.3 Đối tuợng (object) là một thực thể phần mềm bao bọc các thuộc tinh và các phương thức liên quan. Kể từ đây, trong giáo trình này chúng ta sử dụng thuật ngữ đối tưọng (object) để chỉ một đối tượng phần mềm. Hình 6.1 là một minh họa của một đối tượng phần mềm: Chương 6: Lập trình hướng đối tượng 78 Ilình 6.1 Một đối tưọng phần mềm Methods (behavior) Variables (state) Mọi thứ mà đối tượng phần mềm biết (trạng thái) và có thể làm (hành động) được thể hiện qua các thuộc tính và các phương thức. Một đối tượng phần mềm mô phỏng cho chiếc xe đạp sẽ có các thuộc tính đế xác định các trạng thái của chiếc xe đạp như: tốc độ của nó là 10 km trcn giờ, nhịp bàn đạp là 90 vòng trên phút, và bánh răng hiện tại là bánh răng thứ 5. Các thuộc tính này thông thường được xem như thuộc tính thể hiện (instance attribute) bởi vì chúng chứa đựng các trạng thái cho một đối tượng xe đạp cụ thể. Trong kỹ thuật hướng đối tượng thì một đối tượng cụ thể được gọi là một thể hiện (instance). Một đối tượng cụ thể được gọi là một thể hiện (instance). Hình 6.2 minh họa một xe đạp được mô hình như một đối tượng phần mềm: Đối tượng xe dạp pnan mem cung có các phương thức để thắng lại, tăng nhịp đạp hay là chuyến đổi bánh răng. Nó không có phương thức để thay đối tốc độ vì tốc độ của xe đạp có thể tình ra từ hai yếu tố số vòng quay và bánh răng hiện tại. Những phương thức này thông thường được biết như là các phương thước thế hiện (instance method) bởi vì chúng tác động hay thay đổi trạng thái của một đối tượng cụ thể. Khái niệm 6.4 Hình 6.2 Đối tượng phần mềm xe đạp 10 mph 5th gear 90 rpm Chương 6: Lập trình hướng đối tượng 79 6.4. Lóp (Class) Trong thế giới thực thông thường có nhiều loại đối tượng cùng loại. Chẳng hạn chiếc xe đạp của bạn chỉ là một trong hàng tỉ chiếc xe đạp trên thế giới. Tương tự, trong một chương trình hướng đối tượng có thể có nhiều đối tượng cùng loại và chia sẻ những đặc điếm chung. Sử dụng thuật ngừ hướng đối tượng, chúng ta có thế nói rằng chiếc xe đạp của bạn là một thể hiện của lớp xe đạp. Các xe đạp có một vài trạng thái chung (bánh răng hiện tại, số vòng quay hiện tại, hai bánh xe) và các hành động (chuyển bánh răng, giảm tốc). Tuy nhiên, trạng thái của mồi xe đạp là độc lập và có thế khác với các trạng thái của các xe đạp khác. Trước khi tạo ra các xe đạp, các nhà sản xuất thường thiết lập một bảng thiết kế (blueprint) mô tả các đặc điêm và các yếu tố cơ bản của xe đạp. Sau đó hàng loạt xe đạp sè được tạo ra từ bản thiết kế này. Không hiệu quả nếu như tạo ra một bản thiết kế mới cho mồi xe đạp được sản xuất. Trong phần mềm hướng đối tượng cũng có thế có nhiều đối tượng cùng loại chia sẻ những đặc điểm chung như là: các hình chữ nhật, các mẫu tin nhân viên, các đoạn phim, ... Giống như là các nhà sản xuất xe đạp, bạn có thế tạo ra một bảng thiết kế cho các đối tượng này. Một bảng thiết kế phần mềm cho các đối tượng được gọi là lớp (class). Khái niệm 6.5 Lớp (class) là một thiết kế (blueprint) hay một mẫu ban đầu (prototype) định nghĩa các thuộc tinh và các phương thức chung cho tất cả các đối tượng của cùng một loại nào đó. Một đối tượng là một thể hiện cụ thể của một lớp. Trở lại ví dụ về xe đạp chúng ta thấy ràng một lớp Xedap là một bảng thiết kế cho hàng loạt các đối tượng xe đạp được tạo ra. Mồi đối tượng xe đạp là một thế hiện của lớp Xedap và trạng thái của nó có thế khác với các đối tượng xe đạp khác. Ví dụ một xe đạp hiện tại có thế là ở bánh răng thứ 5 trong khi một chiếc khác có thề là ở bánh răng thứ 3. Lớp Xedap sẽ khai báo các thuộc tính thể hiện cần thiết đế chứa đựng bánh răng hiện tại, số vòng quay hiện tại, .. cho mồi đối tượng xe đạp. Lớp Xedap cũng khai báo và cung cấp những thi công cho các phương thức thế hiện để cho phép người đi xe đạp chuyến đối bánh răng, phanh lại, chuyến đối số vòng quay ,.. như Hình 6.3. Chương 6: Lập trình hướng đối tượng 80 Hình 6.3 Khai báo cho lóp Xedap Sau khi bạn đã tạo ra lớp xe đạp, bạn có thể tạo ra bất kỳ đối tượng xe đạp nào từ lớp này. Khi bạn tạo ra một thế hiện của lớp, hệ thống cấp phát đủ bộ nhớ cho đối tượng và tất cả các thuộc tính thế hiện của nó. Mỗi thể hiện sẽ có vùng nhớ riêng cho các thuộc tính thế hiện của nó. Hình 6.4 minh họa hai đối tượng xe đạp khác nhau được tạo ra từ cùng lớp Xedap: Hình 6.4 Hai đối tượng của lóp Xedap HyBi ke YourBike Ngoài các thuộc tính thế hiện, các lớp có thế định nghĩa các thuộc tính lóp (class attribute). Một thuộc tính lớp chứa đựng các thông tin mà được chia sẻ bởi tất cả các thể hiện của lớp. Ví dụ, tất cả xe đạp có cùng số lượng bánh răng. Trong trường hợp này, định nghĩa một thuộc tính thể hiện để giữ số lượng bánh răng là không hiệu quả bởi vì tất cả các vùng nhớ của các thuộc tính thể hiện này đều giữ cùng một giá trị. Trong những trường hợp như thế bạn có thế định nghĩa một thuộc tính lớp để chứa đụng số lượng bánh răng của xe đạp.Tất cả các thế hiện của lớp Xedap sẽ chia thuộc tính này. Một lớp cũng có thế khai báo các phương thức lớp (class methods). Bạn có thể triệu gọi một phương thức lớp trực tiếp từ lớp nhưng ngược lại bạn phải triệu gọi các phương thức thê hiện từ một thể hiện cụ thể nào đó. Chương 6: Lập trình hướng đối tượng 81 Hình 6.5 Lóp và thể hiện của lóp Khái niệm 6.6 Thuộc tinh lóp (class attribute) là một hạng mục dữ liệu liên kết vói một lớp cụ thể mà không liên kết với các thể hiện của lớp. Nó được đinh nghĩa bên trong định nghĩa lớp và đưọc chia sẻ bơi tat cả các thể hiện của lốp. Phuong thúc lóp (class method) là một phương thức được triệu gọi mà không tham khảo tới bất ky một"đối tượng nào! Tat cả các phương thức lớp ảnh hương đến toàn bọ lớp chứ không ảnh hưởng đến một lớp riêng rẽ nào. 6.5. Thuộc tính (Attribute) Các thuộc tính trình bày trạng thái của đối tượng. Các thuộc tính nắm giữ các giá trị dữ liệu trong một đối tượng, chúng định nghĩa một đối tượng đặc thù. Khái niệm 6.7 Thuộc tinh (attribute) là dữ liệu trình bày các đặc điếm về một đối tượng. Một thuộc tính có thể được gán một giá trị chỉ sau khi một đối tượng dựa trên lóp ấy được tạo ra. Một khi các thuộc tính được gán giá trị chúng mô tả một đối tượng. Mọi đối tượng của một lớp phải có cùng các thuộc tính nhưng giá trị của các thuộc tính thì có thể khác nhau. Một thuộc tính của đối tượng có thể nhận các giá trị khác nhau tại những thời điếm khác nhau. Chương 6: Lập trình hướng đối tượng 82 6.6. Phương thức (Method) Các phương thức thực thi các hoạt động của đối tượng. Các phương thức là nhân tố làm thay đổi các thuộc tính của đối tượng. Khái niệm 6.8 Phuong thức (method) có liên quan tới những thứ mà đối tượng có thể làm. Một phương thức đáp ứng một chức năng tác động lên dữ liệu cua đối tượng (thuộc tinh). Các phương thức xác định cách thức hoạt động của một đối tượng và được thực thi khi đối tượng cụ thê được tạo ra.Ví dụ, các hoạt động chung của một đối tượng thuộc lóp Chó là sủa, vẫy tai, chạy, và ăn. Tuy nhiên, chỉ khi một đối tượng cụ thế thuộc lớp Chó được tạo ra thì các phương thức sủa, vầy tai, chạy, và ăn mới được thực thi. Các phương thức mang lại một cách nhìn khác về đối tượng. Khi bạn nhìn vào đối tượng Cửa ra vào bên trong môi trường của bạn (môi trường thế giới thực), một cách đơn giản bạn có thế thấy nó là một đối tượng bất động không có khả năng suy nghỉ. Trong tiếp cận hướng đối tượng cho phát triển hệ thống, Cửa ra vào có thế được liên kểt tới phương thức được giả sử là có thể được thực hiện. Ví dụ, Cửa ra vào có thế mở, nó có thế đóng, nó có thế khóa, hoặc nó có thể mở khóa. Tất cả các phương thức này gắn kết với đối tượng Cửa ra vào và được thực hiện bởi Cửa ra vào chứ không phải một đối lưựng nào khác. 6.7. Thông điệp (Message) Một chương trình hay ứng dụng lớn thường chứa nhiều đối tượng khác nhau. Các đối tượng phần mềm tương tác và giao tiếp với nhau bằng cách gởi các thông điệp (message). Khi đối tượng A muốn đối tượng B thực hiện các phương thức của đổi tượng B thì đối tượng A gỏi một thông điệp tới đối tượng B. Ví dụ đối tượng người đi xe đạp muốn đối tượng xe đạp thực hiện phương thức chuyển đối bánh răng của nó thì đối tượng người đi xe đạp cần phải gởi một thông điệp tới đối tượng xe đạp. Đôi khi đối tượng nhận cần thông tin nhiều hơn để biết chính xác thực hiện công việc gì. Ví dụ khi bạn chuyến bánh răng trên chiếc xe đạp của bạn thì bạn phải chỉ rõ bánh răng nào mà bạn muốn chuyến. Các thông tin này được truyền kèm theo thông điệp và được gọi là các tham số (parameter). Chương 6: Lập trình hướng đối tượng 83 Một thông điệp gồm có: ■ Đối tượng nhận thông điệp ■ Tên của phương thức thực hiện ■ Các tham số mà phương thức cần Khái niệm 6.9 Một thông điệp (message) là một lời yêu cầu một hoạt động. Một thông điệp được truyền khi một đối tượng triệu gọi một haỵ nhiều phương thức của đối tượng khác để yêu cầu thông tin. Khi một đối tượng nhận được một thông điệp, nó thực hiện một phương thức tương ứng. Ví dụ đối tượng xe đạp nhận được thông điệp là chuyến đối bánh răng nó sẽ thực hiện việc tìm kiếm phương thức chuyển đổi bánh răng tương ứng và thực hiện theo yêu cầu của thông điệp mà nó nhận được. 6.8. Tính bao gói (Encapsulation) Trong đối tượng xe đạp, giá trị của các thuộc tính được chuyến đổi bởi các phương thức. Phương thức changeGear() chuyến đối giá trị của thuộc tính currentGear. Thuộc tính speed được chuyển đổi bởi phương thức changeGear() hoặc changRpm(). Trong OOP thì các thuộc tính là trung tâm, là hạt nhân của đối tượng. Các phương thức bao quanh và che giấu đi hạt nhân của đối tượng từ các đối tượng khác trong chương trình.Việc bao gói các thuộc tính của một đối tượng bên trong sự che chở của các phương thức của nó được gọi là sự đóng gói (encapsulation) hay là đóng gói dữ liệu. Đặc tính đóng gói dữ liệu là ý tưởng của các nhà thiết các hệ thống hướng đối tượng. Tuy nhiên, việc áp dụng trong thực tế thì có thể không hoàn toàn như thế. Vì những lý do thực tế mà các đối tượng đôi khi cần phải phơi bày ra một vài thuộc tính này và che giấu đi một vài phương thức kia. Tùy thuộc vào các ngôn ngữ lập trình hướng đối tượng khác nhau, chúng ta có các điều khiển các truy xuất dữ liệu khác nhau. Khái niệm 6.10 Đóng gói (encapsulation) là tiến trình che giấu việc thực thi chi tiết của mọt đối tượnq. Một đối tượng có một giao diện chung cho các đối tượng khác sử dụng đế giao tiếp với nó. Do đặc tính đóng gói mà các chi tiết như: các trạng thái Chương 6: Lập trình hướng đối tượng 84 được lưu trữ như thế nào hay các hành động được thi công ra sao có thể được che giấu đi từ các đối tượng khác. Điều này có nghĩa là các chi tiết riêng của đối tượng có thế được chuyến đổi mà hoàn toàn không ảnh hưởng tới các đối tượng khác có liên hệ với nó. Ví dụ, một người đi xe đạp không cần biết chính xác cơ chế chuyển bánh răng trên xe đạp thực sự làm việc như thế nào nhưng vẫn có thể sử dụng nó. Điều này được gọi là che giấu thông tin. Khái niệm 6.11 Che giấu thông tin (information hiding) là việc ẩn đi các chi tiết của thiết kế hay thi công từ các đối tượng khác. 6.9. Tính thừa kế (Inheritance) Hệ thống hướng đối tượng cho phép các lớp được định nghĩa kế thừa từ các lóp khác. Ví dụ, lớp xe đạp leo núi và xe đạp đua là những lớp con (subclass) của lớp xe đạp. Như vậy ta có thế nói lớp xe đạp là lớp cha (superclass) của lófp xe đạp leo núi và xe đạp đua. Khái niệm 6.12 Thừa kế (inheritance) nghĩa là các hành động (phương thức) và các thuộc tính đưcc định nghĩa trong một lóp có thể được thừa kế hoặc được sử dụng lại bơi lóp khac. Khái niệm 6.13 Lóp cha (superclass) là lcp có các thuộc tính haỵ hành động được thừa hưởng bởi một hay nhiều lợp khác. Lợp con (subclass) là lớp thừa hưởng một vài đặc tính chung của lợp cha và thêm vào những đặc tinh riêng khác. Các lớp con thừa kế thuộc tính và hành động từ lỏfp cha của chúng. Ví dụ, một xe đạp leo núi không những có bánh răng, số vòng quay trên phút và tốc độ giống như mọi xe đạp khác mà còn có thèm một vài loại bánh răng vì thế mà nó cần thêm một thuộc tính là gearRange (loại bánh răng). Các lớp con có thế định nghĩa lại các phương thức được thừa kế để cung cấp các thi công riêng biệt cho các phương thức này. Ví đụ, một xe đạp leo núi sẽ cần một phương thức đặc biệt để chuyến đối bánh răng. Chương 6: Lập trình hướng đối tượng 85 Các lớp con cung cấp các phiên bản đặc biệt của các lớp cha mà không cần phải định nghĩa lại các lóp mới hoàn toàn. Ớ đây, mã lớp cha có thế được sử dụng lại nhiều lần. 6.10.Tính đa hình (Polymorphism) Một khái niệm quan trọng khác có liên quan mật thiết với truyền thông điệp là đa hình (polymorphism). Với đa hình, nếu cùng một hành động (phương thức) ứng dụng cho các đối tượng thuộc các lớp khác nhau thì có thế đưa đến những kết quả khác nhau. Khái niệm 6.14 Đa hình (polymorphism) nghĩa là "nhiều hình thức", hành động cùng tên có thê được thực hiện khác nhau đối với các đối tượng/các lớp khác nhau. Chúng ta hãy xem xét các đối tượng Cửa sổ và Cửa Cái. Cả hai đối tượng có một hành động chung có thể thực hiện là đóng. Nhưng một đối tượng Cửa Cái thực hiện hành động đó có thế khác với cách mà một đối tượng Cửa sổ thực hiện hành động đó. Cửa Cái khép cánh cửa lại trong khi Cửa Số hạ các thanh cừa xuống. Thật vậy, hành động đóng có thế thực hiện một trong hai hình thức khác nhau. Một ví dụ khác là hành động hiển thị. Tùy thuộc vào đối tượng tác động, hành động ấy có thể hiển thị một chuồi, hoặc vc một đường thắng, hoặc là hiến thị một hình. Đa hình có sự liên quan tới việc truyền thông điệp. Đối tượng yêu cầu cần biết hành động nào đế yêu cầu và yêu cầu từ đối tượng nào. Tuy nhiên đối tượng yêu cầu không cần lo lắng về một hành động được hoàn thành như thế nào. Bài tập cuối chương 6 6.1 Trình bày các định nghĩa của các thuật ngữ: ■ Lập trình hướng đối tượng ■ Trừu tượng hóa ■ Đối tượng ■ Lớp ■ Thuộc tính ■ Phương thức ■ Thông điệp Chương 6: Lập trình hướng đối tượng 86 6.2 Phân biệt sự khác nhau giữa lớp và đối tượng, giữa thuộc tính và giá tộ, giữa thông điệp và truyền thông điệp. 6.3 Trình bày các đặc điếm của OOP. 6.4 Những lợi ích có được thông qua thừa kế và bao gói. 6.5 Những thuộc tính và phương thức cơ bản của một cái máy giặt. 6.6 Những thuộc tính và phương thức cơ bản của một chiếc xe hơi. 6.7 Những thuộc tính và phương thức cơ bản của một hình tròn. 6.8 Chỉ ra các đối tượng trong hệ thống rút tiền tự động ATM. 6.9 Chỉ ra các lớp có thể kế thừa từ lóp điện thoại, xe hơi, và động vật. Chương 6: Lập trình hướng đối tượng 87
File đính kèm:
- giao_trinh_lap_trinh_c_tu_co_ban_den_nang_cao.pdf