BÀI 1: MỘT SỐ KHÁI NIỆM CƠ BẢN Mục tiêu: Trong bài này, Anh/Chị cần đạt được những mục tiêu sau: 1. Đối tượng và các thành phần liên quan. 2. Các đặc trưng: đóng gói, che giấu, kế thừa, đa hình. 3. Giới thiệu các ngôn ngữ lập trình hướng đối tượng. Nội dung: 1. Phương pháp lập trình hướng đối tượng Sự ra đời và phát triển của máy tính điện tử kéo theo sự phát triển của các phương pháp lập trình cho máy tính điện tử. Bắt đầu từ phương pháp sơ khai, đơn giản nhất là lập trình tuần tự, tiếp đến là lập trình có cấu trúc và hiện nay, được sử dụng rộng rãi trong các môi trường hiện đại là phương pháp lập trình hướng đối tượng (Object-Oriented Programming, viết tắt là OOP). Phương pháp lập trình có cấu trúc dựa trên cách thức giải quyết bài toán theo hướng chức năng. Theo đó, để giải quyết một bài toán lớn chúng ta phân rã (theo chức năng) thành nhiều bài toán nhỏ, cứ tiếp tục như vậy để đạt được những bài toán đơn giản và có thể triển khai lập trình dễ dàng. Quá trình này gọi là phân tích từ trên xuống “top-down”. Phương pháp này dựa trên ngôn ngữ mô tả bài toán, chủ yếu chúng ta phải tìm ra các “động từ” để đưa ra các chức năng cần giải quyết trong quá trình phân tích. Mỗi bài toán con thu được trong phương pháp này sẽ được lập trình để thực hiện dưới dạng một chương trình con, như vậy để giải quyết bài toán lớn chúng ta sẽ có nhiều mô-đun chương trình con trong một hệ thống chương trình. Hiện nay, trong hầu hết các môi trường lập trình đều cung cấp phương pháp lập trình hướng đối tượng. Các nguyên lý và việc áp dụng phương pháp này được khởi nguồn từ những năm 1960, sau đó vào những năm 1980, các ngôn ngữ lập trình hướng đối tượng được phát triển như Smalltalk, Eiffel, C++ và đặc biệt vào những năm 1990, ngôn ngữ Java được phát triển rất mạnh bởi hãng Sun Microsystems, cho đến nay được sử dụng rộng rãi.
Trang 1BÀI 1: MỘT SỐ KHÁI NIỆM CƠ BẢN
Mục tiêu:
Trong bài này, Anh/Chị cần đạt được những mục tiêu sau:
1 Đối tượng và các thành phần liên quan
2 Các đặc trưng: đóng gói, che giấu, kế thừa, đa hình
3 Giới thiệu các ngôn ngữ lập trình hướng đối tượng
Nội dung:
1 Phương pháp lập trình hướng đối tượng
Sự ra đời và phát triển của máy tính điện tử kéo theo sự phát triển của các phương pháp lập trình cho máy tính điện tử Bắt đầu từ phương pháp sơ khai, đơn giản nhất là lập trình tuần tự, tiếp đến là lập trình có cấu trúc và hiện nay, được sử dụng rộng rãi trong các môi trường hiện đại là phương pháp lập trình hướng đối tượng (Object-Oriented Programming, viết tắt là OOP)
Phương pháp lập trình có cấu trúc dựa trên cách thức giải quyết bài toán theo hướng chức năng Theo đó, để giải quyết một bài toán lớn chúng ta phân rã (theo chức năng) thành nhiều bài toán nhỏ, cứ tiếp tục như vậy để đạt được những bài toán đơn giản và có thể triển khai lập trình dễ dàng Quá trình này gọi là phân tích
từ trên xuống “top-down” Phương pháp này dựa trên ngôn ngữ mô tả bài toán, chủ yếu chúng ta phải tìm ra các “động từ” để đưa ra các chức năng cần giải quyết trong quá trình phân tích Mỗi bài toán con thu được trong phương pháp này sẽ được lập trình để thực hiện dưới dạng một chương trình con, như vậy để giải quyết bài toán lớn chúng ta sẽ có nhiều mô-đun chương trình con trong một hệ thống chương trình Hiện nay, trong hầu hết các môi trường lập trình đều cung cấp phương pháp lập trình hướng đối tượng Các nguyên lý và việc áp dụng phương pháp này được khởi nguồn từ những năm 1960, sau đó vào những năm 1980, các ngôn ngữ lập trình hướng đối tượng được phát triển như Smalltalk, Eiffel, C++ và đặc biệt vào những năm 1990, ngôn ngữ Java được phát triển rất mạnh bởi hãng Sun Microsystems, cho đến nay được sử dụng rộng rãi
Phương pháp lập trình hướng đối tượng dựa trên cách thức giải quyết bài toán theo hướng các đối tượng Theo đó, chúng ta sẽ xem xét về sự tồn tại của các đối tượng trong bài toán, mối quan hệ tương tác giữa chúng để thực hiện mục tiêu đặt ra
Trang 2cho bài toán, từ đó áp dụng phương pháp phân tích và thiết kế từ dưới lên up”) Trong tài liệu này không đi sâu trình bày về phương pháp phân tích và thiết hướng đối tượng, chúng ta sẽ làm quen với phương pháp thông qua ví dụ minh họa
(“bottom-so sánh giữa phương pháp dựa trên chức năng và phương pháp dựa trên đối tượng như sau
Để minh họa, chúng ta xem xét bài toán quản lý sinh viên chẳng hạn
Hình vẽ 1.1: Minh họa bài toán quản lý sinh viên
Rõ ràng, theo hướng chức năng chúng ta đơn giản có thể liệt kê các công việc thực hiện gồm: cập nhật hồ sơ sinh viên; lên kế hoạch đào tạo; tổ chức thi và lên điểm; Ở đây chúng ta đã phân rã bài toán cần làm thành các công việc (hay chức năng) nhỏ, như vậy về phía lập trình cơ bản xây dựng các mô-đun chương trình con
để giải quyết từng công việc này Đối với phương pháp giải quyết dựa trên đối tượng, chúng ta xem xét bài toán này cần có các đối tượng sinh viên, các đối tượng giáo viên, các đối tượng người quản lý, các đối tượng môn học, Trong đó, mỗi loại có thể có nhiều đối tượng khác nhau như sinh viên có thể lên đến hàng nghìn đối tượng Số lượng cho mỗi loại đối tượng là khác nhau và phụ thuộc vào từng bài toán cụ thể Sau đó sẽ xem xét mối quan hệ tương tác giữa các đối tượng này để thực hiện các mục tiêu của bài toán đặt ra
Phương pháp lập trình hướng đối tượng phát sinh nhiều khái niệm mới, yêu cầu người lập trình cần nắm vững và chúng sẽ được trình bày ở phần tiếp sau
2 Các khái niệm, đặc trưng của lập trình hướng đối tượng
2.1 Các khái niệm cơ bản trong lập trình hướng đối tượng
Trang 3- Đối tượng (objects): là các thể hiện trên bộ nhớ của một gói gồm các biến và hàm trong chương trình phần mềm Trong thực tế khái niệm này rất rộng, nó ám chỉ đến mọi sự vật, hiện tượng của thế giới thực Tuy nhiên, khái niệm đối tượng trong lập trình (hay còn gọi là đối tượng phần mềm – software objects) sẽ hạn hẹp hơn nhiều, chủ yếu đề cập đến khía cạnh thông tin của các đối tượng Do đó, chúng ta sẽ
có các đối tượng trong không gian thực của bài toán, tương ứng là các đối tượng trong không gian của chương trình
Ví dụ về các đối tượng như các sinh viên, giáo viên, môn học, lớp học, hay đối tượng là những chiếc xe máy, xe ô-tô, thậm chí là các bánh xe, cánh quạt,
Chúng ta có thể phân loại gồm đối tượng vô hình và hữu hình Trong ví dụ trên thì môn học, lớp học là các đối tượng vô hình, còn sinh viên, giáo viên,… là các đối tượng hữu hình
- Thuộc tính (properties): là các thành phần (dưới dạng các biến - variables) trong đối tượng để mô tả thông tin dữ liệu hay trạng thái (states) của đối tượng (Hình vẽ 1.2) Ví dụ các đối tượng sinh viên có thuộc tính là họ và tên, ngày-tháng-năm sinh, quê quán, hay các đối tượng môn học có tên môn học, số tín chỉ, điều kiện tiên quyết,
- Phương thức (methods): là các thành phần (dưới dạng các hàm) trong đối tượng để mô tả hành vi (behavior) hay khả năng xử lý của đối tượng (Hình vẽ 1.2) Các phương thức khi thực hiện sẽ xử lý trên các thuộc tính và có thể sẽ làm biến đối trạng thái của đối tượng, tức làm thay đổi giá trị trong các thuộc tính Ví dụ các đối tượng xe ô-tô có phương thức khởi động máy, tăng/giảm ga, chuyển số, hay các đối tượng sinh viên có phương thức nhận bài kiểm tra, làm bài kiểm tra, tham dự buổi học
Hình vẽ 1.2: Đối tượng và các thành phần của đối tượng
- Thông điệp (messages): Chúng ta thấy rằng, các đối tượng phần mềm sẽ quan
hệ và tương tác với nhau nhằm để thực hiện mục tiêu của bài toán đặt ra Khi một đối tượng A muốn một đối tượng B thực hiện một phương thức trên B, thì đối tượng
A phải gửi một thông điệp tương ứng đến đối tượng B Thực chất ở đây là việc đối
Trang 4tượng A gọi thực hiện một phương thức trên đối tượng B Hình vẽ 1.3 sau minh họa cho thông điệp F(x) được gọi bởi đối tượng A đến đối tượng B
Hình vẽ 1.3: Thông điệp từ đối tượng A đến đối tượng B
Một thông điệp sẽ gồm 3 thành phần như sau:
+ Đối tượng (object): xác định thông điệp sẽ chuyển đến, hay địa chỉ nơi đối tượng được thể hiện trên bộ nhớ mà phương thức sẽ được thực hiện Hình vẽ 1.3 minh họa thông điệp với thành phần đối tượng là B
+ Tên phương thức (method) cần gọi: trong Hình vẽ 1.3 có tên phương thức là
“F”
+ Các tham số truyền cho phương thức (parameters): trong Hình vẽ 1.3 có tham
số là “x” được truyền cho lời gọi phương thức “F” trên đối tượng B
- Lớp đối tượng (classes, hay gọi tắt là lớp): Trong chương trình hướng đối tượng, có thể xuất hiện nhiều đối tượng có cùng kiểu (hay cùng đặc trưng) như các hình chữ nhật, các công nhân, Do đó, một lớp đối tượng được xem như là một bản thiết kế chi tiết để định nghĩa các thành phần (thuộc tính và phương thức) cho tất cả các đối tượng cùng một kiểu
Lớp là một khái niệm trừu tượng, nó đóng vai trò như bản mẫu cho việc tạo lập hay xây dựng (tức các thể hiện - instance) các đối tượng trong chương trình Hình
vẽ 1.4 sau minh họa cho lớp “Dog” và một đối tượng “Rayne” của “Dog” Lớp
“Dog” có các thuộc tính gồm Color (màu), Eye Color (màu mắt), Height (chiều cao), Length (chiều dài), Weight (cân nặng) và đối tượng “Rayne” có các giá trị thuộc tính tương ứng màu xám, mắt xanh, cao 18 inc, dài 36 inc và nặng 30 pound Các phương thức của “Dog” gồm Sit (ngồi), Lay Down (nằm xuống), Shake (lắc mình), Come (đi)
Trang 5Hình vẽ 1.4: Lớp “Dog” và đối tượng “Rayne”
Hình vẽ 1.5 sau minh họa cho lớp “Student” và các đối tượng sinh viên tương ứng
Hình vẽ 1.5: Lớp “Student” và các đối tượng
2.2 Các đặc trưng của lập trình hướng đối tượng
Cho đến nay, các nhà phát triển ứng dụng cũng như các tác giả nghiên cứu về phương pháp lập trình hướng đối tượng đều đề cập đến 4 đặc trưng cơ bản của phương pháp lập trình hướng đối tượng Các vấn đề chi tiết cũng như phương pháp lập trình khai thác các đặc trưng này sẽ được đề cập ở những chương sau, trong phần này chúng ta điểm qua khái niệm về chúng
- Tính đóng gói (encapsulation): như khái niệm đối tượng đã được đề cập, mỗi đối tượng bao gồm các thành phần thuộc tính để mô tả thông và và các phương thức thể hiện hành vi xử lý thông tin Như vậy, chúng ta đã đóng gói các thành phần này lại với nhau nhằm phản ánh toàn bộ nội dung của đối tượng (minh họa Hình vẽ 1.6) Xem xét từ góc độ lập trình chúng ta thấy trong chương trình gồm các biến chứa dữ liệu, các đơn vị xử lý (hàm) thao tác trên các biến nhằm xử lý và tính toán
Trang 6để thực hiện yêu cầu đặt ra của bài toán Vì thế, các kết quả đóng gói từ các biến và
các hàm để hình thành các lớp đối tượng sẽ đem lại hiệu quả thực hiện chương trình
tốt hơn Mục tiêu đặt ra là đóng gói sao cho phản ánh được nội dung thông tin và
hành vi xử lý thông tin của các lớp đối tượng mà chương trình cần có
Hình vẽ 1.6: Minh họa sự đóng gói các thành phần Tính đóng gói còn làm đơn giản hóa quá trình tương tác xử lý giữa các đối
tượng, bởi vì nó che đi sự phức tạp cố hữu nội tại bên trong một đối tượng Các đối
tượng khác tương tác xử lý thông qua những giao tiếp bên ngoài mà không cần phải
quan tâm đến sự phức tạp bên trong của đối tượng đó Chẳng hạn, một máy tính cá
nhân bản thân bên trong nó chứa những các bộ phận chi tiết, vi mạch phức tạp
nhưng chúng ta sử dụng chỉ cần vài thao tác bấm nút là có thể tương tác với nó
Hình vẽ 1.6: Đóng gói nhằm che đi những chi tiết phức tạp bên trong
- Tính che giấu thông tin (data-hiding): các thành phần sau khi được đóng gói
chúng ta có thể thiết lập cơ chế về khả năng truy xuất xử lý đến các thành phần đó
hay được gọi là phạm vi tác động (scope) Rõ ràng, tính chất này có được là nhờ sự
đóng gói (Hình vẽ 1.8)
Trang 7
Hình vẽ 1.8: Minh họa cơ chế che dấu thông tin
- Tính kế thừa (inheritance): là khái niệm quan trọng trong lập trình hướng đối tượng Thực tế, các đối tượng không hoàn toàn tách rời nhau mà chúng có những quan hệ nhất định Chẳng hạn, con mèo và con chó có chung một số đặc điểm và chúng đều được gọi vật nuôi, hay sinh viên và giáo viên có những đặc điểm chung
vì đều là con người Như vậy, nếu các lớp đối tượng có chung một số đặc điểm và được xem như có quan hệ “là” (is a) với lớp đối tượng khác thì chúng ta nói có sự
kế thừa giữa chúng
Hình vẽ 1.9: Minh họa sự kế thừa giữa các lớp đối tượng
Trong Hình vẽ 1.9, đối tượng “oHuman” và “oPet” đều kế thừa các đặc điểm từ
“oAnimal” tức chúng đều có não bộ (brain = true) và đều có chân, nhưng số chân giữa “oHuman” và “oPet” khác nhau, tương tự giữa “oDog” và “oCat” với “oPet”
- Tính đa hình (polymorphism): là một khái niệm khá phức tạp trong lập trình hướng đối tượng, nó cho phép nhiều đối tượng xử lý, phản hồi cho cùng một thông điệp Một khía cạnh khác, đa hình tức là cùng một đối nhưng được khai thác, xử lý dưới nhiều hình thức khác nhau Tính đa hình được gắn liền với ngữ cảnh trong chương trình, mỗi ngữ cảnh sẽ cho ra một hình thức khai thác, xử lý cụ thể phù hợp Chẳng hạn, Hình vẽ 1.9 cho thấy một con mèo có thể xem như là một vật nuôi, hoặc một động vật, phụ thuộc vào ngữ cảnh khai thác
Bốn tính chất của phương pháp lập trình hướng đối tượng là những tính chất rất đặc trưng, các vấn đề về kỹ thuật và phương pháp sử dụng, khai thác những tính chất này sẽ được trình bày kỹ ở những chương tiếp theo Phần sau chúng
ta xem xét về ngôn ngữ lập trình hướng đối tượng
3 Ngôn ngữ lập trình hướng đối tượng
3.1 Sự phát triển của các ngôn ngữ lập trình hướng đối tượng
Trang 8Về cơ bản, một ngôn ngữ lập trình được gọi là hướng đối tượng nếu nó cung cấp đủ 4 đặc trưng đã xem xét ở trên: tính đóng gói, tính che dấu thông tin, tính kế thừa và tính đa hình
Ngôn ngữ lập trình hướng đối tượng được phát triển cùng với sự hình thành và phát triển của phương pháp lập trình hướng đối tượng (Hình vẽ 1.10) Phương pháp này được khởi xướng vào những năm 1960 tại Na-uy, sau đó được các nhà nghiên cứu, ứng dụng phát triển rất mạnh mẽ Có thể xem ngôn ngữ Simula của Christian Nygaard và cộng sự tại đại học Oslo là ngôn ngữ đầu tiên hỗ trợ hướng đối tượng Sau đó những năm 1970 và 1980 tiếp theo là sự phát triển các ngôn ngữ Smalltalk, Eiffel và C++
Ngôn ngữ Java được xây dựng và phát triển bởi James Gosling và cộng sự tại hãng Sun Microsystems, nó trở nên phổ biến vào cuối những năm 1990 Khác với C++ có sự kết hợp của cả lập trình cấu trúc và hướng đối tượng, Java là ngôn ngữ thuần hướng đối tượng, tức mọi thành phần của chương trình đều phải được đóng gói thành các lớp đối tượng, mọi hành động (actions) đều được thực hiện trên các đối tượng và các lớp Đặc điểm thứ hai của Java khác C++ đó là các đối tượng không cần đến việc giải phóng bộ nhớ sau khi khai thác xử lý xong của người lập trình do cơ chế tự động “thu gom rác” (garbage collection) được cung cấp sẵn bởi Java, điều này giống với 2 ngôn ngữ Smalltalk và Eiffel
Hình vẽ 1.10: Lịch sử phát triển các ngôn ngữ hướng đối tượng
Trong khuôn khổ tài liệu này, chúng ta tập trung khai thác sử dụng ngôn ngữ Java để thể hiện cho các vấn đề của phương pháp lập trình hướng đối tượng Các phần tiếp sau sẽ trình bày cụ thể hơn về ngôn ngữ lập trình Java
3.2 Ngôn ngữ lập trình Java
Java là ngôn ngữ lập trình được sử dụng khá phổ biến hiện nay, nó không chỉ được dùng để phát các ứng dụng cho máy tính mà còn sử dụng để phát triển các ứng dụng cho các thiết bị di động như điện thoại di động, điện thoại thông minh, đặc biệt là lập trình trên hệ điều hành Android
Một số đặc điểm của ngôn ngữ Java:
Smal ltalk
C ++
J ava
C
#
Trang 9- Cấu trúc cú pháp lệnh của ngôn ngữ hầu hết kế thừa từ C/C++ nên dễ tiếp cận nếu đã biết ngôn ngữ C/C++, mềm dẻo và linh hoạt trong sử dụng nhưng cũng rất chặt chẽ về cú pháp
- Là ngôn ngữ lập trình thuần hướng đối tượng như đã đề cập ở trên
- Java áp dụng cơ chế bộ nhớ động cho mọi đối tượng trong chương trình Do
đó, một khai báo biến bất kỳ có kiểu lớp đều dưới dạng tham chiếu (con trỏ), tức là một biến chứa địa chỉ của đối tượng
Về phía hệ thống, các đối tượng khi tạo sẽ được cấp phát bộ nhớ trên vùng heap (trên RAM), do đó mỗi đối tượng có một địa chỉ tương ứng Để truy cập xử lý các đối tượng này chúng ta phải khai báo các biến tham chiếu để lưu giữ địa chỉ của đối tượng (Hình vẽ 1.11)
Hình vẽ 1.11: Minh họa tham chiếu và 02 đối tượng
- Độc lập với môi trường thực hiện Đây là đặc điểm nổi bật của Java, tức một chương trình bằng ngôn ngữ Java sau khi được biên dịch có thể chạy được trên các
hệ nền khác nhau (hệ nền được hiểu bao gồm hệ điều hành và hệ thống phần cứng) Hình vẽ 1.12 minh họa điều này, chương trình sau khi viết và biên dịch có thể chạy trên hệ điều hành Windows, Unix, hoặc MacOS
Trang 10
Hình vẽ 1.12: Sự độc lập với hệ nền của chương trình Java
Với đặc điểm này, giới lập trình Java thường sử dụng khẩu hiệu thể hiện là
“write one, run anywhere” để ám chỉ rằng chương trình Java được viết một lần và chạy ở khắp mọi nơi
Sự độc lập này được thực hiện nhờ cơ chế máy ảo (Java Virtual Machine - JVM) để thực hiện chương trình JVM là một hệ thống phần mềm được xây dựng
và đóng gói sẵn, sau đó cài đặt trên các thiết bị, máy tính với chức năng dùng để thông dịch các câu lệnh của chương trình Java khi thực hiện Quá trình lập trình, biên dịch và chạy chương trình Java được thể hiện qua sơ đồ sau
Hình vẽ 1.13: Quá trình biên dịch và chạy chương trình Java
Trong đó, chương trình Java được lập trình và lưu bằng tệp tin mã nguồn phần
mở rộng *.java (gọi là Java Source) Sau khi biên dịch (compiler) sẽ tạo thành
Trang 11chương trình mã byte (Java Bytecodes) và lưu trữ thành tệp tin có phần mở rộng
*.class, phân phối đến các máy ứng dụng Việc chạy chương trình Java trên một hệ nền nào đó sẽ nhờ máy ảo (Java Virtual Machine) thông dịch các lệnh mã byte về
Java được cung cấp khá nhiều môi trường phần mềm để lập trình như JCreator, Eclipse, NetBean song để thuận tiện trong tài liệu chúng ta sẽ thực hiện trên môi trường Eclipse, đây là phần mềm miễn phí và thuận tiện, chỉ cần copy vào máy để chạy, không cần cài đặt hay cấu hình phức tạp (giao diện có dạng sau)
Hình vẽ 1.14: Giao diện làm việc với Eclipse Tuy nhiên, chúng ta có thể không dùng môi trường mà biên soạn chương trình trên một phần mềm nào đó, lưu lại tệp tin *.java và sử dụng lệnh trực tiếp của JDK
để biên dịch và chạy thử Lệnh biên dịch và chạy thử chương trình Java sử dụng 2 tệp tin “javac.exe” và “java.exe” trong thư mục “BIN” của thư mục đã cài đặt JDK
Cú pháp thực hiện lệnh biên dịch là:
javac tên_tệp_chương_trình.java
Lệnh để chạy thử chương trình là:
Trang 12java tệp_chương_trình
Quy tắc chung của một tệp chương trình bằng Java gồm các phần sau:
/*Phần 1: Khai báo thư viện*/
tự /* và */ nếu viết trên nhiều dòng, còn trên một dòng sử dụng ký hiệu //
Ví dụ một chương trình Java đơn giản (có tên tệp là “vidu.java”):
Kết quả dịch và chạy thử chương trình trên Eclipse (cửa sổ màn hình “Console”
để chứa kết quả chạy và các thông báo khi chạy chương trình) là:
Trang 13
Một số quy tắc/quy ước cần ghi nhớ khi lập trình Java:
- Sử dụng toán tử “new” để sinh đối tượng từ lớp cho việc sử dụng, khai thác và
xử lý, cụ thể: biến = new tên_lớp( tham_số_nếu_có );
- Các từ khóa lệnh viết thường, ví dụ: import, for, if, while, case, return, break, continue ;
- Các tên lớp đối tượng viết dạng chuẩn (chữ cái đầu từ viết HOA, sau đó chữ thường, các từ ghép thành tên hoặc viết tắt cũng theo quy ước này), ví dụ: Scanner, System, JButton, JOptionPane ;
- Các tên hằng được viết chữ hoa, ví dụ: EXIT_ON_CLOSE, PI, CLOSE_OPTION, QUESTION_MESSAGE ;
- Các tên biến (thuộc tính) viết chữ thường;
- Các tên hàm (phương thức) viết từ đầu (động từ) bằng chữ thường, các từ sau
đó theo dạng chuẩn, ví dụ: print, showMessageDialog, setText
- Các lệnh không đứng độc lập, bắt buộc một lệnh cần thực hiện phải trên một đối tượng hoặc trên một lớp nào đó, và thậm chí có thể trên nhiều lớp và đối tượng khi chúng bao nhau Quy tắc chung được viết theo kiểu phân cấp (dùng dấu chấm) như sau:
hoặc lệnh sau sẽ in một dòng chữ lên màn hình,
System.out.print(“Xin chao ban Toi dang hoc JAVA.”);
- Các phép toán, kiểu dữ liệu chuẩn (đơn) đều kế thừa từ C/C++ nên không trình bày chi tiết ở đây, coi như người đọc đã biết C/C++
Chúc các Anh/Chị học tập tốt!
Trang 14BÀI 2: CÁC THÀNH PHẦN CO BẢN TRONG JAVA
Mục tiêu:
Trong bài này, Anh/Chị cần đạt được những mục tiêu sau:
1 Các thành phần cơ bản trong ngôn ngữ Java
2 Các trúc điều khiển trong lập trình java
3 Kỹ thuật vào – ra dữ liệu
4 Kỹ thuật xử lý dữ liệu nâng cao
Nội dung:
1 Các thành phần cơ bản trong ngôn ngữ Java
Cũng giống như ngôn ngữ C/C++, các toán tử của Java để viết biểu thức tính toán trong chương trình được giới thiệu ở bảng sau:
nhân, chia, chia dư *, /, %
Trang 15gán kết hợp +=, -=, *=, %=,
Cách viết các toán tử tương tự các ngôn ngữ lập trình khác, phép ++, có thể
sử dụng tiền tố hoặc hậu tố với mức ưu tiên trước hoặc sau Ví dụ:
x = 5;
y = x++; /*sẽ gán x vào y, sau đó tăng x lên 1*/
y = ++x; /*sẽ tăng x trước và gán x vào y sau.*/
- Phép toán ép kiểu cho phép chúng ta chuyển dữ liệu từ một kiểu này sang kiểu khác, tuy nhiên việc này có thể làm mất dữ liệu nếu kiểu đích có miền giá trị nhỏ hơn Ví dụ:
int x=140276;
short y = (short) x; /*khi hiện kết quả sẽ có y=9204, dữ liệu bị mất*/
Thông thường việc ép kiểu được dùng trong các tham chiếu, trình bày ở phần sau
- Phép toán chia (/) sẽ cho kết quả phần nguyên nếu hai dữ liệu là số nguyên, nếu một dữ liệu số thực sẽ cho kết quả chính xác của phép chia Phép chia dư (%) chỉ thực hiện trên số nguyên Ví dụ:
9/2 sẽ cho kết quả 4,
9.0/2 hoặc 9/2.0 sẽ cho kết quả 4.5
Toán tử dịch bít sang trái <<, sang phải >>, và sang phải không dấu >>> tác động lên từng bít của dữ liệu Ví dụ:
Trang 16- Toán tử lôgíc (&&, ||) để kết nối các biểu thức lôgíc, thường được dùng trong các điều kiện của lệnh rẽ nhánh, lệnh lặp
- Phép toán ba ngôi (?:) sẽ tác động lên ba dữ liệu, cú pháp như sau:
Máy sẽ thực hiện cho kết quả <biểu thức 1> nếu <điều kiện> đúng, ngược lại cho kết quả <biểu thức 2> Ví dụ:
x = (a>b)? a-b : b-a;
sẽ cho kết quả số lớn – số bé giữa hai số a và b
- Đặc biệt phép toán nối (+) để thực hiện nối hai xâu ký tự, nối xâu ký tự với một ký tự, nối xâu ký tự với số nguyên, số thực Ví dụ:
“Ha” + “noi”, hoặc “Hano” + ‘i’ cho kết quả là “Hanoi”,
45 + “ABC” cho kết quả là “45ABC”,
“ABC” + 45 cho kết quả là “ABC45”
Vì trong Java dữ liệu ký tự có thể được xử lý như là số nguyên (theo mã của ký tự) nên phép nối giữa số và ký tự sẽ thực hiện như phép cộng, ví dụ:
Trang 1745 + ‘A’
cho kết quả là 110, vì mã của ký tự ‘A’ là 65
- Biểu thức: biểu thức là kết hợp giữa các phép toán tác động lên dữ liệu thực hiện tính toán và xử lý Trong biểu thức có thể dùng dấu mở đóng ngoặc để ưu tiên thực hiện phép toán cao nhất, nếu không máy sẽ theo thứ tự ưu tiên mặc định (nhân chia trước, cộng trừ sau) Ví dụ:
x = 7+8*2; sẽ cho kết quả x=23, nhưng
y = (7+8)*2; sẽ cho kết quả y=30
- Câu lệnh: câu lệnh (statements) là kết hợp các từ khóa, biểu thức để yêu cầu máy thực hiện một thao tác tính toán, xử lý nào đó Kết thúc một câu lệnh phải có dấu chấm phẩy (;), trên một dòng có thể viết nhiều câu lệnh và một lệnh có thể được viết trên nhiều dòng
- Khối lệnh: khối lệnh (nhóm lệnh) được đóng khung bởi cặp dấu { và }, nếu một hành động xử lý nào đó cần đến nhiều lệnh thì phải sử dụng khối lệnh Kết thúc khối lệnh (sau dấu }) không cần dấu chấm phẩy (;)
- Chú thích trong Java: có 2 cách viết chú thích, đó là viết sau cặp dấu // để chú thích một dòng hoặc viết trong cặp dấu /* và */ để chú thích trên nhiều dòng
Tuy nhiên có thể viết chú thích trong cặp /** và */ và thường được sử dụng cho trong công cụ sinh mã HTML của Java
2 Các cấu trúc điều khiển trong lập trình
Trong bất kỳ một ngôn ngữ lập trình nào của máy tính, ngoài cấu trúc thực hiện lệnh tuần tự là đặc trưng của máy tính điện tử hiện nay đều cung cấp hai cấu trúc điều khiển cơ bản đó là rẽ nhánh và lặp Cũng vậy, trong Java quy tắc thực hiện các cấu trúc đó như sau
Trang 18<giá-trị-n>, nếu bằng ở <giá-trị-k> nào (với k=1,2,…,n) thì thực hiện <nhóm-lệnh-k> tương ứng cho đến khi gặp lệnh break
Ví dụ hiện số lớn trong hai số a và b:
if ( a>b )
System.out.println(“Số lớn là : ” + a);
else
Trang 20tự động thực hiện cho đến khi gặp một lệnh break
Nếu trong một nhóm có nhiều lệnh thì phải đóng khối bằng cặp ký tự { và }, ví dụ:
Trang 212.2 Lệnh lặp (for, while, do-while)
Lệnh lặp cho phép thực hiện một nhóm lệnh nhiều lần trên máy, mặc dù chúng
ta chỉ viết một lần trong chương trình Trong Java có 3 cách viết lệnh lặp gồm for, while, do-while được trình bày chi tiết sau đây
<điều-và lặp lại kiểm tra <điều-kiện> cho đến khi có giá trị sai
Lệnh while máy sẽ kiểm tra <điều-kiện> và thực hiện <nhóm-lệnh-lặp>, quá trình lặp lại cho đến khi <điều-kiện> có giá trị sai
Lệnh do-while máy thực hiện <nhóm-lệnh-lặp> trước, sau đó kiểm tra kiện> nếu đúng sẽ lặp lại thực hiện <nhóm-lệnh-lặp> cho đến khi sai
<điều-Ví dụ hiện các số nguyên lẻ từ 50 đến 100 bằng lệnh for,
for ( i=50; i<=100; i++ )
Trang 22{
if ( i%2!=0 )
{ System.out.println(“ ” + i );
} }
Ví dụ tìm ước số chung lớn nhất của hai số a và b bằng lệnh while,
do-2.3 Lệnh break và continue
Lệnh break để dừng vòng lặp vô điều kiện, thường dùng trong nhóm lệnh lặp
và lệnh “switch” như trên Khi máy gặp lệnh này sẽ kết thúc lệnh lặp cho dù điều kiện lặp có đúng hay sai Cũng như trong lệnh switch ở trên, máy sẽ kết thúc thực
Trang 23Ví dụ sử dụng lệnh continue trong lệnh lặp để hiện các số từ 1 đến 10 và tính tổng các số lẻ như sau:
for ( i=1; i<=10; i++ )
System.out.print( “\n Tong cac so le la : ” + t );
Các cấu trúc lệnh lặp (for, while, do-while) trên có thể sử dụng theo cơ chế
“lồng nhau”, tức là trong nhóm lặp của lệnh này có chứa một lệnh lặp khác Ví dụ hai lệnh lặp for như sau:
for ( i=1; i<5; i+=2 )
là phương thức, trình bày chi tiết ở phần sau
3 Kỹ thuật vào/ra dữ liệu
Nhập và xuất dữ liệu là hai thao tác cơ bản của mọi chương trình phần mềm để tương tác thông tin giữa người dùng với máy tính, do đó chúng thường xuyên được
sử dụng Các thao tác nhập/xuất (hay còn gọi là vào/ra) dữ liệu thực hiện chủ yếu với bàn phím, màn hình và ổ đĩa lưu trữ Các dữ liệu đưa vào từ các thiết bị này gọi
là dữ liệu nguồn (Data Source)
Trang 24
Hình vẽ 2.1: Minh họa nhập/xuất dữ liệu của chương trình
Java cung cấp cơ chế vào/ra dữ liệu theo dòng (stream) ở hai cấp độ, thứ nhất là mức thấp dữ liệu được mã hóa dưới dạng byte và làm việc trực tiếp với các thiết bị, thứ hai là mức cao dữ liệu được định dạng theo từng kiểu để dễ dàng xử lý trong chương trình
Hình vẽ 2.2: Cơ chế vào/ra dữ liệu theo dòng Mỗi dòng mức thấp hay mức cao đều có hai loại đối tượng, đó là dòng nhập dữ liệu (input stream) cung cấp thao tác đọc dữ liệu (read) từ các thiết bị nhập vào chương trình và dòng xuất (output stream) cung cấp thao tác ghi dữ liệu (write) từ chương trình ra các thiết bị
Hình vẽ 2.3: Hai thao tác cơ bản đọc/ghi dữ liệu Chúng ta thường sử dụng hai dòng này ở chế độ bao nhau, tức đối tượng dòng mức cao bao đối tượng dòng mức thấp Các dòng mức thấp làm việc kết nối trực tiếp với các thiết bị và thực hiện đọc/ghi dữ liệu dưới dạng byte Còn dòng mức cao khi đọc sẽ nhận dữ liệu các byte từ dòng mức thấp chuyển hóa thành các dữ liệu
Dòng mức thấp Dòng mức cao
Trang 25theo từng kiểu phù hợp với nhu cầu xử lý trong chương trình, khi xuất thì các dữ liệu sẽ được chuyển hóa thành các byte đưa lên dòng mức thấp để xuất ra các thiết
bị vật lý (hình vẽ sau minh họa điều này)
Hình vẽ 2.4: Cơ chế bao nhau của các dòng mức cao/thấp
Java cung cấp hệ thống khá phong phú dưới dạng các lớp đối tượng Sau đây là danh sách một số lớp đối tượng cơ bản hay dùng
Stt Tên lớp đối tượng
Thuộc thư viện
Chức năng
1 InputStream java.io Nhập dữ liệu mức thấp
2 FileInputStream java.io Đọc dữ liệu tệp tin mức thấp
3 DataInputStream java.io Nhập dữ liệu có định kiểu
4 ObjectInputStream java.io Nhập dữ liệu dạng đối tượng
5 ByteArrayInputStream java.io Đọc dữ liệu dựa trên mảng byte
6 BufferedInputStream java.io Nhập dữ liệu theo vùng nhớ đệm
7 OutputStream java.io Xuất dữ liệu mức thấp
8 FileOutputStream java.io Ghi dữ liệu ra tệp tin mức thấp
9 DataOutputStream java.io Xuất dữ liệu có định kiểu
10 ObjectOutputStream java.io Xuất dữ liệu dạng đối tượng
Chương trình
Trang 2611 ByteArrayOutputStream java.io Xuất dữ liệu dạng mảng byte
12 BufferedOutputStream java.io Xuất dữ liệu theo vùng nhớ đệm
14 Scanner java.util Xử lý nhập dữ liệu đơn giản
15 System java.lang Cung cấp các đối tượng, tham số
16 PrintStream java.io Xuất dữ liệu có thêm các định
dạng Các thiết bị thường sử dụng để nhập/xuất dữ liệu hiện nay gồm màn hình, bàn phím, ổ đĩa và giao tiếp mạng máy tính Tất cả các thiết bị đều có thể áp dụng các lớp đối tượng trên để thực hiện Sau đây chúng ta xem xét nhập/xuất dữ liệu đối với các thiết bị chuẩn
3.1 In dữ liệu ra màn hình
Sử dụng đối tượng “out” thuộc lớp “PrintStream” cung cấp chức năng in dữ liệu ra màn hình dạng Console (là một cửa sổ dạng text để hiển thị các dòng ký tự) Các lệnh thực hiện gồm:
System.out.print( D );
System.out.println( D );
System.out.printf( F, D );
Trong đó “D” là dữ liệu cần in gồm một biểu thức xác định giá trị dữ liệu Lệnh
“println” sẽ xuống dòng sau khi in xong, lệnh “printf” sẽ in dữ liệu có định dạng quy định bởi “F” gồm các thành phần sau:
%[argument_index$][flags][width][.precision]conversion
Phần trong cặp dấu ngoặc [ và ] là tùy chọn, như vậy bắt buộc là dấu “%” và phần “conversion” để quy định chuyển dữ liệu gồm các kiểu hay dùng như “%d”,
“%f”, “%s”, “%x”, “%td”, “%tm”, “%tY”, “%tH”, “%tM”, “%tS” tương ứng dữ liệu in ra là số nguyên, số thực, xâu ký tự, số hexa, ngày, tháng, năm, giờ, phút, giây
“argument_index” cho biết quy định này dành cho dữ liệu thứ mấy trong “D”
Trang 27“flags” quy định trạng thái in dữ liệu như “-”, “0”, “+”, “(” tương ứng để căn trái dữ liệu, thêm số 0 vào bên trái các số, luôn có dấu trước các số, thêm cặp dấu ngoặc ( và ) trước số âm
“width” và “precision” quy định độ rộng dữ liệu in và độ chính xác số thực (số lượng chữ số thập phân)
Ví dụ các lệnh in sau:
System.out.print(“Hello WORLD.”); /*in dòng chữ*/
System.out.println(2012); /*in ra số 2012 và xuống dòng*/
System.out.printf(“Two numbers: %d and %f”, 10, 11.0); /*in định dạng số nguyên và số thực*/
Trang 293.2 Nhập dữ liệu từ bàn phím
Chúng ta sử dụng đối tượng lớp “Scanner” để nhập dữ liệu từ bàn phím, đối tượng này bao đối tượng mức thấp là “System.in” được định nghĩa trong Java để kết nối đến bàn phím Quy tắc tạo đối tượng để nhập như sau:
Scanner = new Scanner(System.in);
Sau đó sử dụng các lệnh nhập trên đối tượng vừa tạo gồm:
System.out.printf(“\nKet qua tong: %f”, a+b);
và kết quả chạy thử trên màn hình là,
3.3 Đọc và ghi dữ liệu trên tệp
Các tệp tin trên ổ đĩa được xử lý thông qua đối tượng lớp “File”, tuy nhiên để đơn giản chúng ta có thể dùng trực tiếp đối tượng “FileInputStream” hoặc
“FileOutputStream” Sau đó sử dụng các đối tượng là dòng nhập/xuất mức cao để bao bên ngoài đối tượng này cho việc đọc/ghi dữ liệu có định kiểu Các đối tượng
Trang 30có thể dùng như “DataInputStream” để đọc dữ liệu và “DataOutputStream” để ghi
dữ liệu có định kiểu, dùng “Scanner” để đọc dữ liệu đơn giản và “PrintStream” để ghi dữ liệu theo định dạng (dạng text)
Chúng ta sẽ làm quen với một phương pháp đọc/ghi dữ liệu trên tệp tin dạng đơn giản (xử lý dạng tệp text)
Hình vẽ 2.5: Phương pháp đọc/ghi tệp dạng đơn giản
- Ghi dữ liệu vào tệp (dạng văn bản):
/*Bước 1: Tạo đối tượng ghi tệp*/
PrintStream = new PrintStream(
Các lệnh ghi dữ liệu giống với in ra màn hình vì đây là xử lý dạng tệp text (“D”
là dữ liệu cần lưu, “F” là định dạng cho dữ liệu) Tên tệp có thể bao gồm cả đường dẫn đầy đủ
Trường hợp muốn ghi thêm dữ liệu nếu tệp đã có nội dung chúng ta chỉ cần thêm giá trị “true” vào lệnh tạo đối tượng “FileOutputStream” ở bước 1 Cụ thể bước 1 sẽ là,
PrintStream = new PrintStream(
Đ
G
Trang 31new FileOutputStream(“tên-tệp”,true));
- Sau đây là 3 bước để đọc dữ liệu từ tệp (dạng văn bản):
/*Bước 1: Tạo đối tượng ghi tệp*/
Scanner = new Scanner(
Các lệnh đọc dữ liệu giống với lệnh nhập dữ liệu từ bàn phím
Quá trình đọc/ghi tệp có thể phát sinh lỗi, đặc biệt ở bước 1 (tạo đối tượng xử
lý tệp) sẽ gặp lỗi nếu tên tệp đưa vào không hợp lệ Các lỗi này được gọi là ngoại lệ (Exception), do đó các bước đọc/ghi tệp được đặt trong cấu trúc xử lý ngoại lệ (sẽ trình bày chi tiết ở phần sau) như sau,
public static void main(String[]ts) throws Exception {
/*nội dung chương trình chính*/
}
Ví dụ sau sẽ ghi dữ liệu chuỗi họ tên có xuống dòng, hai số năm sinh và tiền lương của một nhân viên vào tệp “staff.txt” trên thư mục “F:\”,
Trang 32PrintStream o = new PrintStream(
Ví dụ thứ 2 sẽ thực hiện đọc dữ liệu từ tệp vừa tạo và in ra màn hình kết quả,
Scanner o = new Scanner(
System.out.printf("Ket qua doc:\n%s \n%d %10.2f", t,y,s);
sẽ cho kết quả trên màn hình đúng như các dữ liệu đã lưu trước đó,
Trường hợp cần đọc/ghi dữ liệu có định kiểu và thậm chí là các đối tượng phức tạp chúng ta làm việc với tệp tin dạng nhị phân, sử dụng các lớp đối tượng
“DataInputStream”, “ObjectInputStream” và “DataOutputStream”,
“ObjectOutputStream” Các lệnh đọc/ghi dữ liệu trên các đối tượng này gồm:
Trang 33.readInt() Đọc một số nguyên
.readFloat() Đọc một số thực
.readUTF() Đọc một xâu ký tự dạng UTF
.readObject() Đọc một đối tượng
.writeInt( ) Lưu một số nguyên
.writeFloat( ) Lưu một số thực
.writeUTF( ) Lưu một xâu ký tự dạng UTF
.writeObject() Lưu một đối tượng,
Ví dụ sau đây sẽ thực hiện lưu 100 số đầu của dãy Fibonaci (có dạng 1,1,2,3,5,8, số sau bằng tổng 2 số kế trước) vào tệp có tên “fibonaci.txt”,
DataOutputStream o = new DataOutputStream(
new FileOutputStream("fibonaci.txt"));
int a=1,b=1,c;
for(int i=1;i<=100;i++){
o.writeInt(a); /*lưu số nguyên a vào tệp*/
c=a+b; /*tính số tiếp theo*/
Trang 34int a[]; /*tham chiếu mảng một chiều*/
float b[][]; /*tham chiếu mảng hai chiều*/
Lệnh tạo mảng được thực hiện bởi phép toán “new” và xác định kích thước của mảng, ví dụ
a = new int[100]; /*tạo mảng 100 phần tử gán*/
b = new float[10][20]; /*tạo mảng 10 hàng, 20 cột*/
Việc truy cập xử lý mảng theo chỉ số phần tử (tính từ 0,1,2, ) và trên mảng có phép toán “length” để xác định số phần tử hiện tại, ví dụ
a.length /*để xác định số phần tử của mảng được tham chiếu bởi a*/
b.length /*để xác định số hàng*/
b[i].length /*để xác định số cột ở hàng i*/
Hình vẽ 2.6: Tổ chức dữ liệu mảng một chiều Mặc định khi tạo mảng máy ảo (JVM) sẽ đặt các phần tử về giá trị 0, tuy nhiên chúng ta có thể khai báo mảng và gán dữ liệu trực tiếp, khi đó máy sẽ tự tạo một mảng theo dữ liệu được gán tương ứng, ví dụ:
int a[] = {1,1,2,3,5,8,13}; /*một chiều*/
float b[][] = {{5,3,2},{6,3,7},{3,2,4}}; /*hai chiều*/
Mảng hai chiều thực chất là mảng của mảng một chiều, tức chiều hàng là một mảng mà mỗi phần tử là một tham chiếu đến mảng một chiều khác Do đó mỗi hàng của mảng hai chiều không nhất thiết có độ dài (số phần tử) giống nhau
Trang 35
Hình vẽ 2.7: Minh họa tổ chức mảng hai chiều
Ví dụ sau sẽ tạo một mảng hai chiều 3 hàng, mỗi hàng có số phần tử khác nhau,
int a[][] = new int[3][]; /*mảng hai chiều có 3 hàng*/
a[0] = new int[5]; /*hàng 0 có 5 phần tử*/
a[1] = new int[10]; /*hàng 1 có 10 phần tử*/
a[2] = new int[3]; /*hàng 2 có 3 phần tử*/
Với cơ chế quản lý bộ nhớ động nên Java cung cấp hệ thống gom rác (garbage collection) một cách tự động, tuy nhiên khi cần giải phóng vùng nhớ chúng ta có thể thực hiện trực tiếp bằng hai bước sau:
Bước 1: Đặt các tham chiếu về giá trị null
Bước 2: Sử dụng lệnh System.gc(); để giải phóng bộ nhớ
5 Một số xử lý cơ bản khác
5.1 Xử lý dữ liệu ngày tháng- Date
Kiểu dữ liệu “Date” dùng để xử lý ngày tháng và thời gian, các thành phần cơ bản của “Date” gồm:
Date( ms ) Tạo đối tượng theo số mili giây
Date( d, m, y ) Tạo đối tượng theo ngày, tháng,
năm
.after( d ) Kiểm tra sau ngày khác
.before( d ) Kiểm tra trước ngày khác
Mảng
các
tham
Các hàng (mảng một chiều)
Trang 36.equals( d ) So sánh 2 ngày bằng nhau
Lấy giờ, phút, giây
Ví dụ sau sẽ tạo đối tượng kiểu Date theo thời gian hiện tại của máy và hiện kết quả ra màn hình,
Date d = new Date(System.currentTimeMillis());
System.out.printf("Hien tai la %1$tH:%1$tM:%1$tS - ngay %1$td/%1$tm/%1$tY", d);
có kết quả như sau,
String s = “Hạ Long” + “:” + “Quảng Ninh”;
thậm chí nối các dữ liệu số (kết quả biểu thức) tạo thành xâu,
Trang 37.trim() Cắt bỏ khoảng cách ở hai đầu xâu
.charAt( i ) Lấy ký tự thứ i trong xâu (bắt đầu từ 0)
.substring( i , j ) Lấy xâu con từ i đến j-1 trong xâu
.equals( s ) So sánh bằng với xâu ký tự khác
.startsWith( s ) Kiểm tra có là đoạn con bắt đầu của xâu
.endsWith( s ) Kiểm tra có là đoạn con kết thúc của xâu
.replaceAll ( s, t ) Thay thế đoạn con t cho s trong xâu
.getBytes() Chuyển xâu về mảng byte
.indexOf( s ) Cho biết vị trí xuất hiện đầu của đoạn con
s
.lastIndexOf( s ) Cho biết vị trí xuất hiện cuối của đoạn
con s
.toLowerCase() Chuyển xâu ký tự về dạng chữ thường
.toUpperCase() Chuyển xâu ký tự lên dạng chữ hoa
.compareTo( s ) So sánh với một ký tự khác, trả về >0, <0
nếu nó lớn hơn, nhỏ hơn xâu s theo thứ
tự từ điển String.format( F, D ) Chuyển dữ liệu theo định dạng về xâu
Trong đó lệnh “format” có tham số “F” quy định các định dạng chuyển dữ liệu
“D” về chuỗi, hai tham số này giống như trong lệnh “printf” đã đề cập ở phần trên
Ví dụ sau sẽ chuyển dữ liệu thời gian hiện tại của máy có kiểu “Date” về dạng chuỗi “dd/mm/yyyy”,
Date a = new Date(System.currentTimeMillis());
String s = String.format(“ %1$td / %1$tm / %1$tY ”, a);
Trang 38Ngoài ra, Java cung cấp lớp “Character” để làm việc xử lý trên dữ liệu ký tự gồm một số lệnh cơ bản sau,
5.3 Xử lý số ngẫu nhiên - Random
Java cung cấp lớp đối tượng “Random” để xác định số ngẫu nhiên, cách dùng như sau:
/*Bước 1: Tạo đối tượng Random*/
Random a = new Random();
/*Bước 2: Dùng lệnh để lấy số ngẫu nhiên*/
a.nextInt(); /*lấy số nguyên*/
a.nextInt( g ); /*lấy số nguyên từ 0 đến g-1*/
a.nextFloat(); /*lấy số thực từ 0 đến 1*/
Ví dụ sau sẽ lấy một mảng 2 chiều các số 0,1 ngẫu nhiên sau đó hiện ra màn hình kết quả lấy được,
Random d = new Random();
int a[][] = new int[1+d.nextInt(20)][1+d.nextInt(20)];
for(int i=0;i<a.length;i++)
for(int j=0;j<a[i].length;j++) a[i][j] = d.nextInt(2);
System.out.print("Mang ngau nhien vua lay la");
for(int i=0;i<a.length;i++){
Trang 395.4 Tính toán toán học - Math
Java cung cấp lớp xử lý các phép toán học cơ bản, chúng được sử dụng dưới dạng trực tiếp trên (theo cơ chế “static” sẽ trình bày sau) gồm các lệnh sau:
Math.sqrt(x) Tính căn bậc hai
Math.pow(x,y) Tính lũy thừa x y
Math.sin( x ), cos, asin,
acos,
Tính lượng giác sin, cos, asin, acos
Math.abs( x ) Tính giá trị tuyệt đối
Math.exp( x ) Tính lũy thừa cơ số E
Math.log( x ) Tính logarit tự nhiên
Math.min( x, y ), max Tính min, max
Math.round( x ) Làm tròn số
Math.ceil( x ) Lấy số nguyên cận trên
Trang 40Math.floor( x ) Lấy số nguyên cận dưới
Math.PI, E Lấy số PI, cơ số E
Ví dụ sau sẽ nhập tọa độ x,y của một điểm trên mặt phẳng, tính khoảng cách từ điểm đó đến gốc tọa độ hiện ra màn hình và lấy cận trên, dưới của nó
float x,y; double kc;
Scanner n = new Scanner(System.in);
System.out.print("Nhap toa do x,y:");
5.5 Chuyển đổi dữ liệu
Thông thường trong quá trình xử lý nhu cầu chuyển đổi kiểu dữ liệu là khá cần thiết, chẳng hạn ta có dữ liệu số thực kiểu “double” nhưng giá trị của nó lại chỉ là số nguyên (kiểu “int”) và để thực hiện phép chia dư chắc chắn cần phải chuyển kiểu từ
“double” sang “int” Trường hợp này chúng ta sử dụng cơ chế ép kiểu theo cú pháp: