MỤC LỤC

MỤC LỤC .................................................................................................................................. 1 Đề tài 0. Giới thiệu về Java ......................................................................................................... 6 I. Lịch sử hình thành và phát triển ngôn ngữ lập trình Java ...................................................... 6 I.1. Giới thiệu về Java.......................................................................................................... 6 I.2 Tóm tắt lịch sử hình thành của Java ................................................................................ 6 II. Các đặc trưng của Java ....................................................................................................... 7 II.1. Tính đơn giản............................................................................................................... 7 II.2. Tính hướng đối tượng .................................................................................................. 7 II.3. Tính phân tán ............................................................................................................... 7 II.4. Tính mạnh mẽ .............................................................................................................. 7 II.5. Tính an toàn ................................................................................................................. 7 II.6. Tính trung lập .............................................................................................................. 7 II.7. Tính di động ................................................................................................................ 8 II.8. Tính thông dịch ............................................................................................................ 9 II.9. Tính thực thi cao .......................................................................................................... 9 II.10. Tính đa luồng ............................................................................................................. 9 II.11. Tính động .................................................................................................................. 9 III. Các loại ứng dụng của Java ............................................................................................... 9 IV. Công cụ và môi trường lập trình Java ................................................................................ 9 V. Cài đặt Java ........................................................................................................................ 9 Đề tài 1. Ngôn ngữ mô hình hóa UML ...................................................................................... 12 I. Xây dựng hệ thống phần mềm theo hướng đối tượng ......................................................... 12 I.1 Các khái niệm căn bản của công nghệ hướng đối tượng................................................ 12 I.2 Quy trình chung phát triển hệ thống phần mềm ............................................................ 13 I.3 Những thách thức của ngành công nghiệp phần mềm hiện nay ..................................... 13 II. Lịch sử phát triển ngôn ngữ mô hình hóa UML................................................................. 13 II.1. Tóm tắt lịch sử UML ................................................................................................. 13 II.2. Khái niệm về UML .................................................................................................... 14 II.3 Đặc trưng của UML .................................................................................................... 14 III. Ngôn ngữ UML ............................................................................................................... 15 III.1. Các thành phần của UML ......................................................................................... 15 III.2. Các hướng nhìn (view) ............................................................................................. 15 III.3 Ứng dụng UML trong quy trình làm phần mềm ......................................................... 22 IV. Quy trình Rational Unified Process (RUP) phát triển phần mềm dựa trên UML .............. 23 IV.1. Giới thiệu về RUP .................................................................................................... 23 IV.2. Các nguyên tắc chính của RUP: ................................................................................ 23 IV.3. Vòng đời của phần mềm theo quy trình RUP ............................................................ 24 IV.4. Các công cụ của RUP ............................................................................................... 25 Bài tập .................................................................................................................................. 26 Đề tài 2. Nhập môn Java ........................................................................................................... 27 I. Viết và thực hiện một chương trình Java ............................................................................ 27 I.1 Tìm hiểu mã nguồn một chương trình đơn giản ............................................................ 27 I.2. Thực hiện chương trình Java. ...................................................................................... 27 I.3. Một số chú ý khi lập trình Java .................................................................................... 28

1

I.4. Cấu trúc một chương trình Java ................................................................................... 28 II. Các kiểu dữ liệu trong Java ............................................................................................... 29 II.1 Các kiểu dữ liệu số nguyên ......................................................................................... 29 II.2 Các kiểu số thực.......................................................................................................... 30 II.3 Kiểu ký tự (character) ................................................................................................. 30 II.4 Kiểu logic (boolean) ................................................................................................... 30 II.5 Kiểu chuỗi .................................................................................................................. 30 II.6 Chuyển đổi giữa các kiểu số ........................................................................................ 30 III. Khai báo biến và hằng trong Java .................................................................................... 31 III.1 Quy tắc đặt tên biến ................................................................................................... 31 III.2 Khai báo biến ............................................................................................................ 31 III.3 Biến kiểu mảng .......................................................................................................... 32 III.4 Hằng số (literal) ......................................................................................................... 33 III.5 Phạm vi hoạt động của hằng và biến: ......................................................................... 34 IV. Các toán tử và biểu thức .................................................................................................. 34 IV.1 Các toán tử và thứ tự ưu tiên ...................................................................................... 34 IV.2 Biểu thức ................................................................................................................... 35 V. Các lệnh điều khiển rẽ nhánh ............................................................................................ 35 V.1 Lệnh if ........................................................................................................................ 35 V.2. Lệnh switch …case .................................................................................................... 36 VI. Các lệnh lặp .................................................................................................................... 37 VI.1. Vòng lặp for ............................................................................................................. 37 VI.2. Vòng lặp while ......................................................................................................... 38 VI.3. Vòng lặp do... while ................................................................................................. 38 VI.4. Phép nhảy................................................................................................................. 39 VII. Vào dữ liệu từ bàn phím và xuất dữ liệu ra màn hình ..................................................... 40 VII.1. Lấy giá trị nhập vào từ bàn phím ............................................................................. 40 VII.2 Kết xuất dữ liệu ra màn hình .................................................................................... 41 Bài tập .................................................................................................................................. 42 Đề tài 3. Lập trình hướng đối tượng trong Java ......................................................................... 44 I. Khái niệm lập trình hướng đối tượng (Object-Oriented Programming - OOP) .................... 44 I.1. Khái niệm OOP ........................................................................................................... 44 I.2 Cơ sở lý luận của OOP ................................................................................................. 44 I.3 Trừu tượng hóa ............................................................................................................ 44 II. Tính đóng gói trong Java .................................................................................................. 46 II.1 Khái niệm tính đóng gói.............................................................................................. 46 II.2 Mối quan hệ giữa các class.......................................................................................... 46 II.3 Một số gợi ý khi thiết kế class ..................................................................................... 46 IV. Sử dụng các Class xây dựng sẵn trong thư viện ............................................................... 47 V. Xây dựng Class trong Java ............................................................................................... 48 V.1 Cấu trúc của class ....................................................................................................... 48 V.2 Các thuộc tính thành phần:.......................................................................................... 49 V.3 Các phương thức thành phần....................................................................................... 50 V.4 Gọi và truyền tham số cho phương thức ...................................................................... 51 V.6 Các hàm và phương thức đặc biệt ............................................................................... 51 V.7 Khai báo chồng các phương thức ................................................................................ 52 V.8 Lớp lồng nhau – lớp nội.............................................................................................. 53 2

VI. Tính kế thừa trong Java ................................................................................................... 54 VI.1 Sự kế thừa các thuộc tính và phương thức.................................................................. 54 VI.2 Sự kế thừa đối với các constructor ............................................................................. 57 VII. Tính đa hình trong Java .................................................................................................. 58 VII.1 Sự ép kiểu và gán tham chiếu đối tượng ................................................................... 58 VII.2 Sự ràng buộc động –Dynamic Binding ..................................................................... 58 VIII. Lớp Object ................................................................................................................... 59 IX. Giao diện ........................................................................................................................ 60 IX.1 Cấu trúc của giao diện ............................................................................................... 60 IX.2 Các tính chất của giao diện ........................................................................................ 62 X. Package ............................................................................................................................ 62 X.1 Sử dụng các package trong thư viện Java .................................................................... 62 X.2 Đặt lớp vào package ................................................................................................... 63 Bài tập .................................................................................................................................. 63 Đề tài 4. Lớp và phương thức trừu tượng .................................................................................. 64 I. Khái niệm lớp trừu tượng ................................................................................................... 64 II. Cài đặt lớp và phương thức trừu tượng trong Java ............................................................. 64 Bài tập .................................................................................................................................. 65 Đề tài 5. Lưu trữ và xử lý đối tượng .......................................................................................... 66 I. Lớp Vector và giao diện Enumeration ................................................................................ 66 I.1 Lớp Vector ................................................................................................................... 66 I.2 Giao diện Enumeration................................................................................................. 67 II. Mảng trong Java và lớp ArrayList ..................................................................................... 69 II.1 Mảng trong Java ......................................................................................................... 69 II.2. Các thuật toán cơ bản trên mảng ................................................................................ 70 II.3 Class Arrays ............................................................................................................... 71 III Danh sách trong java và giao diện Lists ............................................................................ 73 Bài tập .................................................................................................................................. 74 Đề tài 6. Các luồng vào ra dữ liệu với file ................................................................................. 75 I. Khái niệm luồng vào ra (I/O stream) .................................................................................. 75 II. Lớp InputStream: .............................................................................................................. 76 III. Lớp OutputStream ........................................................................................................... 77 IV. Lớp FileInputStream ....................................................................................................... 77 V. Lớp FileOutputStream ...................................................................................................... 77 VI. Lớp File .......................................................................................................................... 77 VII. Nhập xuất lọc................................................................................................................. 78 VII.1 Lớp FilterInputStream: ............................................................................................. 79 VII.2 Lớp FilterOutputStream ........................................................................................... 79 VIII. Vào/ra có sử dụng bộ đệm ............................................................................................ 79 VIII.1 Lớp BufferedInputStream: ...................................................................................... 79 VIII.2 Lớp BufferedOutputStream..................................................................................... 79 IX. Lớp RandomAccessFile .................................................................................................. 81 X. Đối tượng System.in ......................................................................................................... 82 XI. Truy cập file ở chế độ tuần tự .......................................................................................... 82 XII. Truy cập file nhị phân .................................................................................................... 86 Bài tập .................................................................................................................................. 86 Đề tài 7. Xử lý ngoại lệ ............................................................................................................. 88 3

..............................................6 Danh sách (Lists) ...................................112 II..........................104 II............................................................... 93 II.103 Đề tài 9........111 II................................................4 JScrollPane ..........................................................................................................................................124 V................................................8 Thanh trượt (Scrollbar) ...................................................119 III....................................................5 Hộp thoại Combo ............................................ 90 V........... Sử dụng ngoại lệ được kiểm soát .....................127 V.............................121 III........ Các phương thức............................................................................................................................................ Vật chứa (Container) ............................................3 Nút đánh dấu (checkbox) ......................................................................................................................................................................................................................... 91 VI.....................................................................114 III................................................................................................... Giới thiệu AWT .......................... Xây dựng một Applet đơn giản .........................128 VI........................1 Cách trình bày FlowLayout:.............. Bài tập ........................................... Truy cập thông tin sự kiện ...................................................................106 V.........110 II.100 V............ Lập trình giao diện đồ họa GUI ...................................2 Cách trình bày GridLayout: ..........................2 Nhãn (Label) ................... 92 Đề tài 8.............................113 III...............................128 VI........................................................................................................ Các tình huống sử dụng ngoại lệ ...............................................................................107 VI..... Các hộp thoại ..... Khái niệm và cơ sở xử lý sự kiện .............................................. Xây dựng một ngoại lệ ...................113 III........................................................... Giới thiệu về các thành phần GUI cơ bản ................... 99 IV.......................................................................... Các lớp thích nghi ......... Xử lý các sự kiện trên window ............................................................................................................128 VI................................................................111 II... Các thẻ HTML của Applet.................................1 JFrame ............................... An ninh và khả năng của Applet ....................................................... 93 I........130 Đề tài 11.......................................................................................2 JPanel .......... Cấu trúc cây kế thừa các xử lý ngoại lệ ....................................................................... Xử lý các sự kiện trong Java ..............................102 Bài tập ....128 V.....................................................3 Hộp thoại chọn màu ............ Threading .......................I..................................................7 Ô văn bản (text field) và vùng văn bản (text areas) .................130 Bài tập ..........................................................................................................................................................................104 I.... Thành phần Menu ....................................................................................................108 Đề tài 10.................................................................... lập trình đồ họa và bắt sự kiện của applet ..........2 Hộp thoại chọn File ..................................................................129 VI...................................... Bộ quản lý cách trình bày (Layout Manager) .............................................. Xử lý các sự kiện chuột .....118 III...........3 JDialog .......................................4 Nút chọn (radio button)...............................................................................111 II....... Cấu trúc cơ bản và vòng đời của một Applet ...1 Hộp thoại thông báo ................................... Cơ sở quản lý ngoại lệ trong Java ........................................................................................................................................................................................................................................................................................................................................................................................... 88 II..... 88 III..................................................................................132 4 .................................... 89 IV........................................................ Applet ...........................................................117 III................................................ Ứng dụng Applet với của sổ Popup ..............................................................................................123 IV............................................................................................................................................................115 III.........................1 Nút nhấn ..............113 III.......................................................128 V.....3 Cách trình bày BorderLayout ........................................... 98 III..............................110 I.............................................106 IV.................104 III.........................................................................

........................................................5 Đợi một thread kết thúc công việc ...........................................................................2 Nhóm thread .............................................................. Các từ khóa của Java .........................................................................................................................................................................135 III............................132 I..........................3 Tạm dừng và phục hồi một thread ..........................137 IV.....................................................................................1 Khái niệm: ..........143 Phụ lục A..................... Lớp Thread ..................................3 Quản lý các ngoại lệ của thread .................................146 5 ......................................................................................................................................................................................................141 Bài tập ...................................................... Đồng bộ thread ............................................... Các thuộc tính của thread ..........145 Tài liệu tham khảo ................................I...........................................136 IV.............................................................................................1 Độ ưu tiên của thread ...139 V.....................................133 III........................................................4 Giải phóng thời gian cho CPU ..........................................139 V............................................................................................140 V..........................................................134 III..........................................................................3 Các bước để tạo một thread .............1 Tình trạng “đua tranh” ...........132 II.3 Đối tượng điều kiện ................................................144 Phụ lục B Một số hàm hay sử dụng ...................................... Khái niệm thread..........................................................................134 III...................... Điều khiển các thread .....2..............135 IV....................................................136 IV...................................................................................................... Các trạng thái của thread.........132 I...........................138 IV..................................138 V..138 IV.....................................................132 I.........................................................................................................................................................................................................1 Interrupt một thread ........................................2 Khóa đối tượng ..........................................................................................2 Dừng một thread .

5 (chuyển sang gọi là phiên bản 5. Giới thiệu về Java Java là một ngôn ngữ lập trình mạnh đang được sử dụng rất rộng rãi hiện nay trên toàn thế giới. Sau đó nhóm đã phải mất cả năm 1993 và nửa đầu 1994 để đi tiếp thị công nghệ của mình. Khi làm việc với Java. Giới thiệu về Java I. Bảng sau cho thấy sự phát triển thư viện Java qua các phiên bản: Phiên bản Số các Class và Interface 6 . ngôn ngữ mới thiên về hướng đối tượng (Object Oriented) của C++ hơn là hướng thủ tục như Pascal.2 làm cho Java tiến gần tới mục tiêu “viết một lần. Java được biết đến không chỉ là một ngôn ngữ lập trình mà là một platform – một môi trường và công nghệ phát triển – riêng biệt. Run Anywhere). các chương trình viết bằng Java có môi trường thực thi riêng với các tính năng bảo mật. khả năng triển khai trên nhiều hệ điều hành khác nhau và nhiều tính năng ưu việt khác chúng ta sẽ xem xét trong phần sau.4 là sự phát triển mở rộng tiếp theo của phiên bản 1. do các hãng khác nhau sử dụng các chíp xử lý (CPUs) khác nhau nên một đặc tính quan trọng mà ngôn ngữ này phải có là độc lập với các dòng CPUs khác nhau – gọi là đặc tính di động. I.3. Từ năm 1994.Đề tài 0. Đây chính là minh chứng rõ ràng về sức mạnh của Java đã nhanh chóng được cộng đồng người sử dụng internet biết đến và là tiền đề để Java phát triển rực rỡ như ngày hôm nay. Do đó. Bên cạnh đó. Sun Fellow và James Gosling có ý tưởng phát minh ra một ngôn ngữ lập trình nhỏ gọn có thể thực thi được trên các thiết bị dạng như bộ chuyển kênh của truyền hình cáp vì các thiết bị kiểu này có bộ nhớ nhỏ. một nhóm kỹ sư của hãng SUN bao gồm Patrick Naughton. do hãng SUN phát triển trên nền UNIX nên họ sử dụng ngôn ngữ lập trình C++ là chủ yếu. Nhóm đã mở một dự án có tên là Green để hiện thực hóa ý tưởng này. sự phát triển của Internet đã tạo cơ hội để Java phát triển nhanh chóng. Năm 1998 đánh đấu bước chuyển mình mạnh mẽ của Java với sự ra đời của phiên bản 1. Phiên bản 1.0 của Java ra đời vào năm 1996. dự án Green cho ra đời sản phẩm đầu tiên có tên là “*7” nhưng đã không được chào đón như mong đợi. Để giải quyết vấn đề di động. Lịch sử hình thành và phát triển ngôn ngữ lập trình Java I.2” ý nói tới sự có mặt đồng thời của 2 phiên bản “Standard Edition” là Micro Edition và Enterprise Edition trong Java. Các nhân viên tiếp thị của Java gọi đây là phiên bản “Java 2 Standard Edition Software Development Kit Version 1.2. người lập trình được sở hữu một thư viện lớn.0) đánh dấu sự tích hợp đầy đủ nhất các công nghệ Java. Nhóm đã phát triển một trình duyệt có tên là HotJava cho phép các chương trình Java nhúng được trong đó (applet). Ban đầu nhóm đặt tên cho ngôn ngữ mới là “Oak” nhưng sau đó được chuyển thành Java do Oak cũng đã là tên một ngôn ngữ lập trình khác. nhóm đã sử dụng ý tưởng của kỹ sư Niklaus Wirth – người sáng lập ngôn ngữ Pascal – về việc sử dụng cơ chế thông dịch và máy ảo (virtual machine). sau đó là phiên bản 1. Ngoài ra.1. Về nền tảng ngôn ngữ. Các phiên bản 1. Phiên bản đầu tiên 1. 1. chạy khắp nơi” (Write once.1 mặc dù khá mạnh nhưng cũng còn nhiều hạn chế.2 Tóm tắt lịch sử hình thành của Java Năm 1991. Năm 1992. có tính mở với một lượng mã nguồn tái sử dụng khổng lồ luôn có trên internet. Trên thực tế.

Trong Java chỉ có thừa kế đơn mà không có tính đa thừa kế như của C++. Java đã phát triển tới phiên bản 1.0 211 477 1524 1840 2723 3270 Hiện tại.4 5. Tính phân tán Java cho phép lập trình truy cập các đối tượng từ xa thông qua các giao thức HTTP. Tính an toàn Ngôn ngữ Java được thiết kế để tránh các sự cố:  Nạp chồng stack lúc runtime. Các công nghệ JSP. II. structures. Điều này có được là do mã nguồn chương trình không được biên dịch thành mã máy ngay mà thành mã Bytecode. Với Java.6.6.2.1 1. Tính hướng đối tượng Như đã trình bày ở trên. II. Lập trình viên không cần quan tâm đến thao tác cấp phát và giải phóng bộ nhớ. 7 .3. Tính mạnh mẽ Việc loại bỏ con trỏ làm tăng độ tin cậy của chương trình.3 1.2 1. II. bộ nhớ được giải phóng tự động.  Đọc và ghi file tự do II. virtual base class. Java hoàn toàn thích hợp cho các ứng dụng Internet. FTP bằng các phương thức như RMI hay Socket. Tính trung lập Các chương trình viết bằng Java không bị phụ thuộc vào hệ điều hành.5. Java được phát triển từ C++ nên nó là ngôn ngữ lập trình hướng đối tượng.1. II.1. Servlet cho phép xây dựng các website tương tác với các tính năng thực thi tối ưu II. Các đặc trưng của Java Java được biết đến với các đặc trưng sau: II.  Ảnh hưởng tới bộ nhớ nằm ngoài phạm vi được cấp phát. union.4.0 1. operator overloading. Tuy nhiên tính đa thừa kế được biểu hiện thông qua việc sử dụng các Interface. con trỏ. Tính đơn giản Java được phát triển dựa trên C++ nhưng lược bớt đi hoặc thay thế các khái niệm khó hiểu như header file.

IBM Bytecode Sparc Trình biên dịch 8 . Từ mã nguồn -> Bytecodes: Trình biên dịch Java. Người ta có thể xem nó như một hệ điều hành thu nhỏ. Ngày nay. Việc không nhất quán của phần cứng làm cho máy ảo phải sử dụng ngăn xếp để lưu trữ các thông tin sau:  Các “Frame” chứa các trạng thái của các phương thức. Nó có tập hợp các lệnh logic để xác định các hoạt động của máy tính. Chẳng hạn kiểu dữ liệu int của Java luôn là 4 byte (32 bit) trong khi kiểu int của C++ có thể hiểu là 2 byte hoặc 4 byte. Trình thông dịch trên mỗi máy sẽ chuyển tập lệnh này thành chương trình thực thi. Trong các phiên bản đầu của Java.  Các toán hạng của mã bytecode. Trình biên dịch chuyển mã nguồn thành tập các lệnh của máy ảo mà không phụ thuộc vào phần cứng cụ thể.class  Quản lý bộ nhớ  Dọn “rác”. JVM thiết lập các lớp trừu tượng cho phần cứng bên dưới.  Các tham số truyền cho phương thức. Máy ảo tạo ra một môi trường bên trong để thực thi các lệnh bằng cách:  Nạp các file . Từ Bytecodes -> machine code: Trình thông dịch Virtual machine. vấn đề giao diện đồ họa cho người sử dụng (GUI) chưa được xử lý triệt để và phụ thuộc vào hệ máy. mã đã biên dịch.7. Tính di động Không giống C++ và C. Thiết kế này giúp cho trình biên dịch luôn có số bytecode như nhau trên mọi hệ máy và sau đó phát sinh mã máy theo khuôn dạng cố định. các kiểu dữ liệu nguyên thủy của Java được cấp phát một lượng bộ nhớ cố định. Trình thông dịch Java (Java Interpreter) Macintosh Java Virtual Machine – JVM Máy ảo là một phần mềm dựa trên cơ sở máy tính ảo. thư viện GUI của Java đã được viết lại hoàn toàn và có tính độc lập cao giúp cho chương trình Java có giao diện giống nhau trên mọi hệ máy. II. thu hồi bộ nhớ cấp cho các biến không còn được sử dụng. hệ điều hành.  Các biến cục bộ.Khi đem mã Bytecode này chạy trên hệ máy tính nào thì một trình thông dịch virtual machine (Java Vitual Machine-JVM) sẽ thông dịch chúng sang mã máy tương ứng để thực thi. Mã nguồn -> ByteCodes -> machine code.

Ngày nay. lập trình viên có thể cùng lúc quản lý nhiều tiến trình khác nhau.II. Điều này giúp cho việc cài đặt các thuật toán song song bằng Java trên các máy tính nhiều CPU được dễ dàng hơn. những mã bytecode giống nhau sẽ chỉ cần thông dịch một lần. công nghệ này liên tục được cải tiến và cho kết quả vượt trội so với các trình thông dịch truyền thống. II.8. Mỗi môi trường cung cấp cho lập trình viên những tiện ích lập trình ở mức độ khác nhau. RMI. IV.0_02). II. Một số IDE thông dụng là:  Netbeans (miễn phí tại http://www.netbeans. Các loại ứng dụng của Java       Ứng dụng console: Không có giao diện GUI.0_02 (nếu phiên bản cài là jdk1. JSP: Các file nhúng mã Java và HTML. Tuy nhiên đây lại là giải pháp cho tính di động.  Jcreator (thương mại). Thư mục cài đặt mặc định của Java trên Windows là C:\Program Files\Java\jdk1.  Jbuilder (thương mại). V. đặc biệt trong các ứng dụng thời gian thực. II. III. tối ưu chúng để nâng cao tốc độc thực hiện.sun. Các phương thức mới có thể được cài đặt thêm vào các lớp đối tượng hay các giao diện trong thư viện của chương trình đang chạy.6. Servlet: Các class thực thi phía web server. Ví dụ như JIT có thể quản lý các đoạn mã được sử dụng thường xuyên trong chương trình. Ứng dụng đồ hoạ: Có giao diện GUI. Sau đó cài đặt như ứng dụng bình thường. Công cụ và môi trường lập trình Java Hiện nay có rất nhiều môi trường phát triển Java (Integrated Development Environment IDE).org/).6.11. Tính động Các chương trình Java có thể được nâng cấp mà không ảnh hưởng tới người sử dụng. JMS: Xây dựng ứng dụng bởi nhiều thành phần ghép lại. Tính thực thi cao Java sử dụng công nghệ Just-In-Time (JIT) giúp quá trình thông dịch thực hiện nhanh hơn. Tính đa luồng Với chương trình Java. Trong đó có chứa các thư mục với ý nghĩa sau: 9 . Tính thông dịch Trình thông dịch Java sẽ thông dịch mã bytecode sang mã máy nơi mà nó được cài đặt.10. Ứng dụng EJB. Quá trình này cũng làm các chương trình Java chạy chậm hơn.org).9. Applet: Nhúng trong các trang Web.  Eclipse (miễn phí http://www. Cài đặt Java Java phiên bản Java mới nhất có thể download tại địa chỉ http://java.eclipse. Với công nghệ này. giao tiếp từ xa.com/j2se.

. 'javac' Cú pháp:javac [options] sourcecodename. */). 1. Chọn System 10 ..bin Chứa các công cụ và trình biên dịch Java demo Chứa các chương trình Java Demo docs Chứa các tài liệu mô tả thư viện của Java includes Chứa các file dùng để biên dịch các đoạn mã nguồn viết bằng ngôn ngữ khác (native). các phương thức của một lớp.java Chương trình tìm lỗi . jre Chứa các file lưu thông tin môi trường lúc thực thi lib Chứa các file thư viện src Chứa mã nguồn java Trong thư mục \bin có chữa các công cụ chính của Java: Trình biên dịch. 'javadoc' Tiện ích này cho phép ta tạo ra tệp HTML dựa trên các lời giải thích trong mã chương trình (phần nằm trong cặp dấu /*.java Trình thông dịch. Mở Control Panel 2.java hay jdb -host -password [options] sourcecodename. 'javap' javap dịch ngược bytecode và in ra thông tin về các thuộc tính (các trường). 'java' Cú pháp:java [options] classname Trình dịch ngược.Debug. Cú pháp:javadoc [options] sourcecodename. 'jdb„ Cú pháp:jdb [options] sourcecodename. Cú pháp:javap [options] classname Công cụ sinh tài liệu..java Cài đặt đường dẫn mặc định.

Chọn Variable Path . Thêm đường dẫn C:\Program Files\Java\jdk1.0_02\bin vào biến môi trường Path . Chọn Tab Advanced 4.3.6. Chọn Environment Variables 5.Chọn Edit 11 .

Công ty ký hợp đồng với ứng viên hoặc từ chối Trong ví dụ trên có sự tham gia của hai đối tượng “công ty” và “ứng viên”. object = name + attributes + operations Hệ thống hướng đối tượng nếu được mô hình đúng sẽ rất linh hoạt. Xét cho cùng thì mọi quy trình nghiệp vụ trong thực tế đều là sự tương tác của các đối tượng theo một trình tự nhằm đạt được một mục đích cụ thể. Sự trao đổi thông tin giữa hai đối tượng này cho thấy mối quan hệ phụ thuộc giữa chúng (dependence). …và một danh mục các mặt hàng. lớp trâu. quản lý. Các hệ thống phần mềm hướng đối tượng cũng được cài đặt bởi các ngôn ngữ lập trình hướng đối tượng. Lớp là sự trừu tượng hóa các đối tượng thực tế theo phạm vi nghiệp vụ. Ứng viên gửi hồ sơ dự tuyển tới công ty 3.1 Các khái niệm căn bản của công nghệ hướng đối tượng Hướng đối tượng là một công nghệ để sản sinh ra các mô hình phản ánh một cách tự nhiên các nghiệp vụ thực tế.Đề tài 1.… Mỗi đối tượng là một biểu hiện thực tế của một lớp. Ví dụ như nghiệp vụ tuyển nhân sự cho một công ty có thể được tóm tắt qua một chuỗi các tương tác như sau: 1. Phát triển một hệ thống phần mềm theo hướng đối tượng dựa trên 5 khái niệm cơ bản: Lớp (class). lớp 4 chân lại bao gồm các lớp như lớp mèo. các đối tượng và mối quan hệ giữa chúng phản ánh quy trình nghiệp vụ. Nói cách khác. Lấy ví dụ về hệ thống quản lý sinh viên của trường ĐHBK Hà Nội cần quản lý rất nhiều đối tượng sinh viên khác nhau nhưng có thể chỉ được trừu tượng hóa thành một lớp đối tượng có tên SinhVien chẳng hạn. dễ hiệu chỉnh. Xây dựng hệ thống phần mềm theo hướng đối tượng I. Công ty đưa ra thông báo tuyển nhân sự tới các ứng viên có nhu cầu 2. đối tượng (object). Ngôn ngữ mô hình hóa UML I. thông điệp (mesage). các hệ thống phần mềm theo công nghệ hướng đối tượng phản ánh một cách tự nhiên và trung thực nghiệp vụ thực tế và có khả năng đáp ứng các thay đổi dễ dàng.…cho thấy mối quan hệ dạng khác: các nhân viên làm công việc quản lý tất nhiên cũng là nhân viên của công ty nhưng có thêm các thuộc tính riêng biệt – một quan hệ kế thừa (inheritance). Lấy ví dụ: lớp động vật có vú bao gồm lớp động vật 4 chân. Trong một hệ thống bán hàng. Sự chi tiết phụ thuộc vào phạm vi nghiệp vụ. Công ty duyệt hồ sơ và gửi giấy hẹn phỏng vấn tới ứng viên 4. Đối tượng thực tế thì có vô số thuộc tính và hành vi nhưng chỉ thuộc tính và hành vi trong phạm vi nghiệp vụ là được xét đến. Vì vậy. Một ví dụ khác là trong hệ thống quản lý nhân sự chúng ta có các đối tượng như: nhân viên. được cài đặt dễ dàng bằng các ngôn ngữ hướng đối tượng. thừa kế (inheritance) và đa hình (polymorphism). 12 . Công ty phỏng vấn ứng viên 5. mỗi đơn hàng bao gồm trong nó các thông tin về khách hàng. ngày giờ. Sự trừu tượng hóa diễn ra ở nhiều cấp độ. Sự trừu tượng hóa một lớp đối tượng cho ta kết quả một tập các thuộc tính (attributes) và các hành vi (operations) đặc trưng cho bất kỳ đối tượng nào thuộc lớp đó. Khi này ta nói rằng giữa đơn hàng và mặt hàng tồn tại một quan hệ bao gồm (aggregation) Mục tiêu của công nghệ hướng đối tượng chính là thể hiện được các đối tượng và mối quan hệ giữa chúng vào trong các hệ thống phần mềm.

2 Quy trình chung phát triển hệ thống phần mềm Xây dựng một hệ thống phần mềm hướng đối tượng cũng tuân theo quy trình chung như mọi công nghệ khác: 1.… I. Thêm vào đó. Sau đó Ivar Jacobson cũng sớm gia nhập nhóm này. Tuy nhiên. các công ty này lại muốn sử dụng các công cụ phần mềm hỗ trợ các quy trình của họ. James Rumbaugh đã hợp tác cùng Grady Booch tại công ty phần mềm Rational Software Corporation để cùng xây dựng một quy trình thống nhất dựa trên kết quả của từng người. Mỗi một quy trình có một tập ký hiệu mô hình riêng để truyền đạt và diễn tả các kết quả phân tích và thiết kế. Rumbaugh và Jacobson đã làm việc độc lập và đã đề xuất các quy trình thỏa mãn yêu cầu này. nơi mà vai trò của quá trình khảo sát. lĩnh vực này vẫn cần được chuẩn hóa hơn nữa. Điều này cho thấy việc cần thiết phải có một quy trình với tập ký hiệu thống nhất. Nhiều nhà nghiên cứu phương pháp trong đó có Booch. Deployment: Triển khai Theo nguyên tắc chung này. Sự phân tán về không gian làm việc 4. Sức ép về thời gian hoàn thành 3. Năm 1994. Implementation: Cài đặt 5.3 Những thách thức của ngành công nghiệp phần mềm hiện nay Mặc dù đã ứng dụng các công nghệ tiến tiến và quy trình phát triển chuẩn hóa nhưng ngành công nghiệp phần mềm vẫn phải đối mặt với những thách thức: 1. Design: Thiết kế 4. mô hình hướng chức năng.1. nhóm đã cho xuất 13 . Analysis : Phân tích 3. Test: Kiểm thử 6. các công ty phần mềm đã rất khó khăn trong việc cung cấp các công cụ này. II. các công ty khác nhau. Điều này dẫn tới một đòi hỏi phải có một quy trình làm phần mềm tiếp cận theo hướng phân tích và thiết kế hướng đối tượng (Object Oriented Analyze and Design . phân tích còn bị xem nhẹ cũng như các công ty còn đang bỡ ngỡ với sự mở rộng về quy mô và thiếu nhân lực chuyên môn về phân tích thiết kế. Sự thay đổi các yêu cầu của người sử dụng Những thách thức này có thể nói là gắn liền với mọi công ty phần mềm đặc biệt là ở Việt Nam.OOP) để xây dựng các ứng dụng. Năm 1996. I. Tóm tắt lịch sử UML Những năm 1980 là thời kỳ bùng nổ số lượng các công ty phần mềm sử dụng ngôn ngữ lập trình hướng đối tượng(Object Oriented Programming . mỗi công ty lại ứng dụng những công nghệ khác nhau để phát triển ứng dụng như các mô hình water fall. thậm chí là các bộ phận khác nhau của cùng một công ty đã sử dụng các quy trình khác nhau. Requirements : Thu thập yêu cầu 2. Vào đầu những năm 1990.Hướng đối tượng không chỉ là một lý thuyết mà đã được chứng minh bằng những ứng dụng rất thành công trong thực tế ở nhiều lĩnh vực khác nhau. Với quá nhiều quy trình khác nhau. Sự gia tăng về quy mô từ nhỏ đến lớn của ứng dụng 2. Đa dạng về nội dung 5.OOAD). Lịch sử phát triển ngôn ngữ mô hình hóa UML II.

OMG tiếp tục xem xét lại UML và đến năm 2001 thì phiên bản UML 1.1. Mục đích của UML là:  Trở thành ngôn ngữ mô hình mà tất cả mọi người làm mô hình có thể sử dụng  Tập trung hướng tới giải quyết các vấn đề tồn tại trong phát triển phần mềm hiện nay. OMG là một tổ chức phi lợi nhuận chuyên xúc tiến việc sử dụng công nghệ hướng đối tượng trong ngành công nghiệp phần mềm thông qua việc đưa ra các hướng dẫn và đặc tả OOP. nó nói lên các nguyên tắc của UML:  Thống nhất phương thức. Canon. một tổ chức có tên Object Management Group (OMG) đã mời nhóm đệ trình một ngôn ngữ mô hình.V.4 ra đời. II.bản phiên bản đầu tiên của UML tới cộng đồng phát triển phần mềm và yêu cầu phản hồi. Inc.2.. Thuật ngữ “Unified” ở đây có một ý nghĩa quan trọng. UML là một ngôn ngữ đã được OMG chuẩn hóa và được đặc tả rõ ràng. ký hiệu. Oracle và Rational Software đã nhận thấy lợi ích của UML và đã nhận lời tài trợ cho các dự án về UML của OMG.  Mô hình Use-case và mô hình hoạt động mô tả các yêu cầu và các luồng công việc trong hệ thống.. Sun Microsystems. Các thành viên của OMG ban đầu là 3Com Corporation. Hiện nay OMG đã phát hành tới phiên bản UML 2. mô hình hoạt động (activity diagrams) mô tả các hành vi động của các đối tượng trong hệ thống cũng như các thông điệp giữa chúng. UML không phải là một quy trình. Data General. mô hình trạng thái (state diagrams). Năm 1997. Tất cả các mô hình.  Mô hình triển khai (deployment diagrams) mô tả việc triển khai phần mềm trên một môi trường xác định.0 và đang nghiên cứu phiên bản 2. IBM. Cũng cùng thời gian đó. Các tập đoàn lớn như HP. và Unisys Corporation.  Các mô hình cấu trúc hỗn hợp (composite structure diagrams) mô tả sự hợp tác cũng như các đặc điểm về cài đặt. Philips Telecommunications N. Khái niệm về UML UML – Unified Modeling Language là một ngôn ngữ dùng các sơ đồ và mô hình thống nhất để mô hình các hệ thống phần mềm. 14 . Các đặc tính của UML bao gồm:  Mô hình class (class diagrams) mô tả cấu trúc tĩnh của hệ thống và mối quan hệ giữa các đối tượng  Mô hình tương tác (interaction diagrams). Hewlett-Packard.3 Đặc trưng của UML Hiện nay.  Đơn giản nhất có thể trong khi vẫn mô hình được phần lớn các ứng dụng. II. Microsoft. thuật ngữ  Gắn kết giữa các chu trình phát triển  Không phụ thuộc vào lĩnh vực ứng dụng  Không phụ thuộc vào ngôn ngữ lập trình và môi trường thực hiện  Không phụ thuộc vào quy trình phát triển  Gắn kết chặt chẽ các khái niệm nội tại của hệ thống. sơ đồ của UML đều theo hướng đối tượng.  Nâng cao tính tái sử dụng các thành phần của một hệ thống phần mềm  UML là một ngôn ngữ diễn tả. American Airlines.

inheritance và aggregation. message (thông điệp) và mối quan hệ giữa chúng bao gồm quan hệ dependence. Một phần tử mô hình có thể được sử dụng trong nhiều sơ đồ nhưng chúng luôn có cùng ý nghĩa và ký hiệu giống nhau. object.0 bao gồm 13 loại sơ đồ khác nhau. Một hệ thống không thể chỉ được mô tả bởi một sơ đồ. Các General Mechanisms (các đặc tả chung mở rộng): Mô tả các thông tin chú thích. Ngôn ngữ UML III.    Các Diagrams (các sơ đồ): Các sơ đồ bao gồm các phần tử hình vẽ dùng để mô tả nôi dung của các View. UML có đầy đủ các mô hình và sơ đồ để thể hiện hầu hêt các khía cạnh của hệ thống phần mềm.1.2. 15 .III. Các thành phần của ngôn ngữ UML bao gồm:  Các Views (các hướng nhìn): Các view thể hiện các cách nhìn khác nhau tới hệ thống. Các Model Elements (các phần tử mô hình): Các khái niệm được sử dụng trong các sơ đồ và các phần tử của sơ đồ diễn tả các khái niệm phổ biến của công nghệ hướng đối tượng như class. III. UML 2. thuật ngữ. Các hướng nhìn (view) Use-case view: Đây là hướng nhìn về mặt chức năng của hệ thống được thực hiện bởi các tác nhân bên ngoài. ngữ nghĩa của các phần tử mô hình. Các thành phần của UML Xét trên khía cạnh ngôn ngữ diễn tả. Nhiều hướng nhìn khác nhau cho ta nhiều sơ đồ mô tả đầy đủ về hệ thống. Các hướng nhìn cũng liên kết ngôn ngữ mô hình với các quy trình được chọn cho việc phát triển hệ thống.

• • • • • • use-case phải • • •đủ. Dòng phụ •••••••••••••••••••••••••• •••••••••••••••••••••••••• •••••••••••••••••••••••••• •••••••••••••••••••••••••• •••••••••••••••••••••••••• 16 •••••••••••••••••••••••••• . Dòng • • • 7. Phạm vi của use-case • • • • • • • • • • tác nhân•chính • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • 4.  Các use-case cần có tính độc lập tương đối để dễ tổ chức nhóm làm việc và có tính • • • • • sử•dụng•cao. người làm mô hình có thể sử dụng mô tả bằng văn bản chi tiết cho mỗi use-case • • • detail). Mục tiêu • • • • • • 3. • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • tái • • • • • Bên cạnh sơ đồ.•chúng • • • • • hợp• • • • • • • •pháp•đi từ • • • •đến • • • • •  Các • • • • • • • đầy • • • • được tổng • • theo phương • • • • tối đa • • tối thiểu (ban đầu mở rộng tối đa các use-case có thể sau đó thu hẹp lại theo nhu • • • • • •khách • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • cầu • • • hàng). Các • • • • • • • 5. Tiền điều kiện • • • • • • • • • • •chính • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • 6. • • •mô•tả cần • • • bảo • • • • • •tin • • • • • • • • • • • • • • • • • • • • • • • • • • (text • • • • Mỗi • • • • đảm • • các thông sau: 1.ud Primary Use Cases •••••••••••••••••••••••••• •••••••••••••••••••••••••• • • • • • • • • • • • • • • • • HÖ thèng b¸n hµng qua m¹ng Interrnet • • • • • • • • • • • • • • • • • •••••••••• ••••••••• Chän hµng •••••••••••••••••••••••••• Xem chi tiÕt •••••••••••••••••••••••••• • • • • • • • • • • • • • • • • • • • • • • s¶n phÈm • • • • • • • • • • • • • • • • • • • • • • • • • • •••• •Kh¸ch • • • • • • • • • • • • • • • • • • • • • • • • • hµng Göi th«ng • • • hµng • • • • • • • • • • • • • • • • • • • • ••• CËp nhËt giá • • • • • • • • • • • • • • • • • • • • • • ph¶n•håi • • • • • • • • • • • • • • • • • • • • • • • • • • tin • • • •••••••••••••••••••••••••• •••••••••••••••••••••••••• LËp • • • • • • • • • • • • • • • • • • • • • • • • • • §¨ng ký • • • • • • • • •®¬n mua • • • • • • • • • • • • • •••• hµng kh¸ch hµng Qu¶n lý • • • • • • • • • • • • • danh môc • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • ••••• hµng hãa •Qu¶n•trÞ hÖ• • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • •• •• thèng Tr¶ lêi • • • • • • • • • • • • • • • • • • • kh¸ch • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • hµng • • • • • • • • • • • • • • • • •tin • • • • • • • • th«ng • •••••••••••••••••••••••••• Nh©n viªn kinh• • • • • • • • • • • • • Theo dâi • ••••••• • • hµng ®¬n • • • doanh mÆt hµng CËp nhËt •••••••••••••••••••••••••• •••••••••••••••••••••••••• •••••••••••••••••••••••••• •••••••••••••••••••••••••• •••••••••••••••••••••••••• •••••••••••••••••••••••••• •••••••••••••••••••••••••• Các nguyên tắc cho việc xây dựng use-case view là:  Các • • • • • • • • hình thành • • cơ • • • • bên • • • vào • • • • • • • • • • • • • use-case được • • • • • • •trên • • sở nhìn•từ • • •ngoài • • •trong hệ•thống • • • • • (out-> in). Tên use-case • • • • • • • • • • • • •của use-case• • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • 2.

nhắc nhở. chúng có thể được tác ra thành các use-case nhỏ hơn theo hai dạng:  Include: use-case mới được tách ra và được bao gồm trong use-case chính một cách vô điều kiện uc Use Case Model Use Case Include Use Case Principal «include»  Extend: use-case mới xảy ra khi một điều kiện xảy ra trong use-case chính. Bằng chứng tai nạn không đầy đủ 1a1. Công ty bảo hiểm từ chối yêu cầu. Người đòi bồi thường gửi đơn yêu cầu với các dữ liệu bằng chứng về tai nạn 2. Người đòi bồi thường không có chính sách bảo hiểm hợp lệ 2a1. Công ty bảo hiểm trả tiền bảo hiểm Dòng phụ 1a. (Công ty bảo hiểm sẽ làm gì trong trường hợp này???) 4a. Công ty bảo hiểm điều đình với người đòi bảo hiểm và đồng ý trả bảo hiểm Trong trường hợp các use-case quá phức tạp và chưa được mô tả rõ ràng. Không có đại lý nào rảnh rỗi 3a1.8. Hậu điều kiện Sau đây là một ví dụ về use-case text detail: Use-case: Đòi tiền bồi thường Phạm vi: Công ty Bảo hiểm PCM Actor chính: Người đòi bồi thường Dòng chính 1. ghi lại và kết thúc xử lý vụ việc 3a. Người đòi bồi thường gửi lại các dữ liệu thiếu 2a. Công ty bảo hiểm phân công cho một đại lý xác minh trường hợp này 4. Ngoại lệ 9. Công ty bảo hiểm xác nhận người viết đơn có quyền lợi bảo hiểm hợp lệ 3. 17 . nhắc nhở. ghi lại và kết thúc xử lý vụ việc 4b. Vụ tai nạn vi phạm chính sách bảo hiểm cơ bản 4a1. Công ty bảo hiểm yêu cầu dữ liệu thiếu 1a2. Đại lý đối chiếu tất cả các chi tiết trong đơn theo chính sách bảo hiểm của công ty 5. Công ty bảo hiểm từ chối yêu cầu. Vụ tai nạn chỉ vi phạm chính sách bảo hiểm nhỏ 4b1.

Các cấu trúc tĩnh (static structure): Cấu trúc tĩnh được mô hình bằng UML chính là các class diagrams. Sau đây là một số sơ đồ quan trọng thường được sử dụng. Các khái niệm Mô hình hóa Classes Attributes Operations Object Ví dụ về mô hình class: 18 . Đây là sự mô hình các khái niệm trong ứng dụng. use-case view giúp ta trả lời câu hỏi WHAT? về hệ thống. Logical views Đây là hướng nhìn cho biết các chức năng được thiết kế vào trong hệ thống như thế nào (HOW?) thông qua việc mô tả các cấu trúc tĩnh và các hành vi động của hệ thống. các đặc điểm nội tại cũng như mối quan hệ giữa chúng.uc Use Case Model Use Case Principal «extend» Use Case Extend Nói chung.

new: int + getStatus() : OrderStatus • •.delivered: int + • • • • • • • LineItem • •.listPrice: number • • • • title: • • • • • • • • • • • • • • • • • • • • • • string + getItem() : StockItem • • • • •+ •getQuantity() •int • • • • • ••••••: • property set + setItem(StockItem) : void ••••••••••••••••••• + setQuantity(int) : void •• •• •• •• •• ••••••••••••••••••• ••••••••••••••••••• ••••••••••••••••••• ••••••••••••••••••• property get • • getAuthor() : • • • • • • • • • • + • • • • • • string + getCatalogNumber() : string + ••••••• :•••• • • getCostPrice()• number • • • • + getListPrice() : number + getTitle() : string •••••••••••••••••• property set + setAuthor(string) : void • • setCatalogNumber(string) :•void + ••••••••••••• •• + setCostPrice(number) : void + • • • • • • • • • • void • • setListPrice(number)•: • • • • • + setTitle(string) : void •••••• •••••• •••••• •••••• •••••• •••••••••••••••••••••••••• ShoppingBasket •••••••••••••••••••••••••• ••••••••• ••••••••• ••••••••• ••••••••• ••••••••• ••••••••• ••••••••• •••••••••••••••••••••• • • -• •deliveryAddress: •String • • • • • • •••••••• ••• .• • • • • • int• • • • • • • • • •set• • • • • • • • • • • • • packed: • property • + setDate(Date) : void • • • • • • • • • • • • • • • • setDeliveryInstructions(String) :• • • + • • • • • • • • • • • • • • void + setLineItem(LineItem) : void + •••••••••• • : •• • • • • • • • • • • • • • • • • setOrderNumber(String) •void • • • + setStatus(OrderStatus) : void -account •••••••••••••••••••••••••• • • .emailAddress: String • • -• •name: • • • • • • • • • • • • • • • • • • String billingAddress: String closed: boolean Account • • • • • • • • • • + createNewAccount() : void • + •loadAccountDetails() • void • • • • • •••••••••• : •• + markAccountClosed() : void • + •retrieveAccountDetails() :• • • • • • • • • • • • • • • • • • void + submitNewAccountDetails() : void + •validateUser(String.• • • • • • • • int • • • • • getLineItem() :• • • • • • • • • • • dispatched: + getOrderNumber() : String .date: Date • • • • + •addLineItem() : • • • • • • • • • • • • • • -• •orderNumber: String • • • • • • • • • • • • • • • • • void •• ••••••• createNewBasket() : void -basket + + loadAccountHistory() : void • • • • + •deleteItem() : • • • • • • • • • • • • • • • + •loadOpenOrders() :• • • • • • • • • • • • • • • • • void • • • • • • • • • void + processOrder() : void property get property get • • • • • • • • • • • • • • • • • • • • • • • • • • + •getAccount() •Account • • • • • • • • • • •• •••: •••• + getLineItem() : LineItem + getDate() : Date property set • • • • + •setLineItem(LineItem)•: void• • • • • • • • + •getLineItem()• LineItem• • • • • • • • • •••••••••• •• • •• ••• :•••• + getOrderNumber() : String property set •••• •••••••••••••••••••••••••• ••••••••••••••••• + setAccount(Account) : void -history -account + setDate(Date) : void • • • • • • • • • • • • • • • • • • • • • • • • • • + •setLineItem(LineItem)• void• • • • • • • • • • • • • • • • • :• • + setOrderNumber(String) : void •••••••••••••••••••••••••• •••••••••••••••••••••••••• •••••••••••••••••••••••••• •••••••••••••••••••••••••• •••••••••••••••••••••••••• •••••••••••••••••••••••••• •••••••••••••••••••••••••• •••••••••••••••••••••••••• •••••••••••••••••••••••••• •••••••••••••••••••••••••• •••••••••••••••••••••••••• •••••••••••••••••••••••••• •••••••••••••••••••••••••• •••••••••••••••••••••••••• •••••••••••••••••••••••••• •••••••••••••••••••••••••• •••••••••••••••••••••••••• •••••••••••••••••••••••••• •••••••••••••••••••••••••• •••••••••••••••••••••••••• •••••••••••••••••••••••••• •••••••••••••••••••••••••• •••••••••••••••••••••••••• •••••••••••••••••••••••••• •••••••••••••••••••••••••• •••••••••••••••••••••••••• •••••••••••••••••••••••••• •••••••••••••••••••••••••• •••••••••••••••••••••••••• ••••• ••••• ••••• ••••• ••••• ••••• •••••••••••••••••••••••••• •••••••••••••••••••••••••• •••••••••••••••••••••••••• •••••••••••••••••••••••••• •••••••••••••••••••••••••• •••••••••••••••••••••••••• •••••••••••••••••••••••••• •••••••••••••••••••••••••• •••••••••••••••••••••••••• •••••••••••••••••••••••••• •••••••••••••••••••••••••• •••••••••••••••••••••••••• •••••••••••••••••••••••••• •••••••••••••••••••••••••• •••••••••••••••••••••••••• •••••••••••••••••••••••••• •••••••••••••••••••••••••• •••••••••••••••••••••••••• •••••••••••••••••••••••••• •••••••••••••••••••••••••• •••••••••••••••••••••••••• •••••••••••••••••••••••••• •••••••••••••••••••••••••• •••••••••••••••••••••••••• •••••••••••••••••••••••••• •••••••••••••••••••••••••• •••••••••••••••••••••••••• •••••••••••••••••••••••••• •••••••••••••••••••••••••• •••••••••••••••••••••••••• •••••••••••••••••••••••••• •••••••••••••••••••••••••• •••••••••••••••••••••••••• •••••••••••••••••••••••••• •••••••••••••••••••••••••• •••••••••••••••••••••••••• •••••••••••••••••••••••••• •••••••••••••••••••••••••• •••••••••••••••••••••••••• •••••••••••••••••••••••••• •••••••••••••••••••••••••• •••••••••••••••••••••••••• •••••••••••••••••••••••••• •••••••••••••••••••••••••• •••••••••••••••••••••••••• •••••••••••••••••••••••••• •••••••••••••••••••••••••• •••••••••••••••••••••••••• •••••••••••••••••••••••••• •••••••••••••••••••••••••• •••••••••••••••••••••••••• •••••••••••••••••••••••••• Các hành vi động: State machine: 19 .shoppingBasketNumber: String .cd Jav a Model •••••••••••••••••••••••••• •••••••••••••••••••••••••• date: Date Order •••••••••••••••••••••••••• •••••••••••••••••••••••••• quantity: int LineItem •••••••••••••••••••••••••• StockItem ••••••••• ••••••••• ••••••••• ••••••••• ••••••••• ••••••••• ••••••••• ••••••••• ••••••••• ••••••••• ••••••••• ••••••••• ••••••••• ••••••••• ••••••••• ••••••••• ••••••••• ••••••••• ••••••••• ••••••••• ••••••••• ••••••••• ••••••••• ••••••••• ••••••••• ••••••••• ••••••••• ••••••••• ••••••••• ••••••••• ••••••••• ••••••••• ••••••••• ••••••••• ••••••••• ••••••••• ••••••••• ••••••••• ••••••••• ••••••••• ••••••••• ••••••••• ••••••••• ••••••••• ••••••••• ••••••••• • • • • Author: string • • • • • • • • • • • • • • • ••••••• catalogNumber: string .•••••••••• •• • • • • • • • • • • • • • • • • deliveryInstructions: String • • • • • • • • • •property • • • • • • • • • • • • • • get .• • • • • number -item • • costPrice: • • • • • • • • • • • • • • • • • .orderNumber: String «enumeration» • • • • • • • • • • • • • • • • checkForOutstandingOrders() :• • • + • • • • • • • • • • • • • • void OrderStatus property get enum • • • • • • • • • • • getDate() : Date • • • • • • • • • + •••••••• ••••• -status .closed: int + getDeliveryInstructions() : String . String) • • • • •• ••••••••••••• property get + getBasket() : ShoppingBasket •••••••••••••••••••• + getBillingAddress() : String + getClosed() : boolean • + •getDeliveryAddress()• String • • • • •••••••••• :••• + getEmailAddress() : String + •getName() • String • • • • • • • • •• ••••• : ••• + getOrder() : Order • property • • • • • • • • • • • • • • • • • • • set + setBasket(ShoppingBasket) : void + setBillingAddress(String) : void • + •setClosed(boolean) : • • • • • • • • • • • • • • • • • • void + setDeliveryAddress(String) : void • + •setEmailAddress(String) •void • • • ••••••••••••: •• + setName(String) : void • + •setOrder(Order) :• • • • • • • • • • • • • • • • • • void • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • Transaction • • • • • • • • • • •••••• .

Trạng thái của đối tượng bị thay đổi bởi một hành vi nào đó. 20 .Đây là mô hình mô tả việc chuyển đổi trạng thái của đối tượng trong quá trình tham gia các hoạt động nghiệp vụ của hệ thống. Sơ đồ hành động (activity diagrams): Đây là sơ đồ mô tả luồng nghiệp vụ trong hệ thống.

Sơ đồ tương tác (interaction diagram): Đây là sơ đồ mô tả sự tương tác giữa các đối tượng theo trình tự thời gian (còn gọi là sequence diagram). • • • •• • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • Sơ đồ triển khai (Deployment Diagram): •••••••••••••••••••••••••• •••••••••••••••••••••••••• ••••• •••••••••••••••••••••••••• •••••••••••••••••••••••••• •••••••••••••••••••••••••• •••••••••••••••••••••••••• ••••• • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • 21• • • • • • • •••••••••••••••••••••••••• •••••••••••••••••••••••••• ••••• •••••••••••••••••••••••••• •••••••••••••••••••••••••• . Các sơ đồ sequence có thể được mô tả ở mức hệ thống (Sequence System – chỉ có user tương tác với hệ thống) hoặc mức chi tiết (Sequence Detail – Các đối tượng và thông điệp giữa chúng đã được định hình): • • • sd Sequence • • • • • • • • • • •V • • • • • • ••••• • •••••••••••••••••••••••••• Khach mua DangKy •••••••••••••••••••••••••• hang Page • • • • • • • • • •Nhap•thong tin dang ky • • • • • • • • • •••••• •••••••••••••••••••••••••• •••••••••••••••••••••••••• •••••••••••••••••••••••••• •••••••••••••••••••••••••• Click "Dang Ky" • • • • • • •C • • • • • • • • • • • • • • • • • • • M •••••••••••••••••••••••••• AccountUtilities AccountTable •••••••••••••••••••••••••• •••••••••••••••••••••••••• •••••••••••••••••••••••••• • • • • • • • • DangKyKhachHang() • • • • • • • • • • • ••••••• •••••••••••••••••••••••••• •••••••••••••••••••••••••• ••••• ••••• ••••• ••••• ••••• XacNhanThongTinDangKy() ••••• ••••• ••••• •• • • • • sd MuaHang ••••••••• • • • • • • • • • • • •V • • • • • • • •••••••••••• C• • • • • •M• • • • • • • • • • • • • ••••• • • • • • • • • • • • • •• • • • • • •• • • • • • • • • • • • • • • • • • • Khach Hang TrangChu TrangDanhMucSanPham SanPhamUtilities SanPhamTable •• • • • • • •••••••••••••• • • • • • • • • • • • • • • • • • • • • •••••••••••• • • • • • • • • • • • • • • • • • • • •••••••••••••• ••• •• •••••••••••••• •••• •• • • • • • •••••••••••••• • • • • • • • • • • • • • • • • • • • • •••••••••••• • • • • • • • • • • • • • • • • • • • •••••••••••••• ••• •• •••••••••••••• •••• Chon xem san pham theo hang Redirect •• • • • • • •••••••••••••• • • • • • • • • • • • • • • • • • • • • •••••••••••• • • • • • • • • • • • • • • • • • • • •••••••••••••• ••• •• •••••••••••••• •••• •• • • • • • • ••••••••••• • • • • • • • • •• •••• • • • • • •••••••••••••• • • • • • • • • • • • • • • • • • •LayDanhSachSanPham• • • • • • • • • • • • • • • • • • • • ••••••• •• • ••• •• •••• • • • • • •••••••••••••• • • • • • • • • • • • • • • • • • • • • •••••••••••• • • • • • • • • • • • • • • • • • • • ••••••• •••••••• • • • • • •••••••••••••• • • • • • • • • • • • • • • • • • • • • •••••••••••• • • • • • • • • • • • • • • • • • • • ••••••• •••••••• •• • ••• •• •••• HienThi • • • • • •••••••••••••• • • • • • • • • • • • • • • • • • • • • •••••••••••• • • • • • • • • • • • • • • • • • • • ••••••• •••••••• •• • ••• •• •••• • • • • • •••••••••••••• • • • • • • • • • • • • • • • • • • • • •••••••••••• • • • • • • • • • • • • • • • • • • • •••••••••••••• ••• •• •••••••••••••• •••• •• Các class trong • • thống được chia ba tách biệt: • • • • • • • • • – C (View) • • • • • •••••••••••••• • •hệ • • • • • • • • • thành • • loại • •••••••••M•(Model) – V • • • • • • • • • • • • • • • Các class • •chịu • • • • • • •hiển • • giao • • • tương tác với•• • • sử•dụng. V thị • •M • • •••••••••••••• • •mô•hình • • • •thông tin•đối•tượng •••••••••••• • • • • • • • • C • •nơi• • • • • • • • lưu trữ dữ liệu được • • • • • hóa • • • • • • • • • • • • quản lý trong khi các class • • • • • • • • • •• • • • • từ • • • • là • khiển việc dữ liệu từ•M được đưa tới • • diện V như•thế nào hoặc • • lý • • • • •cầu từ • • • • điều giao xử các yêu V sau•đó • • • • • vào • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • cập nhật • • M.•các•class• • • • • • trách nhiệm • • • • • diện • • • • người • • •• (Control).

3 Ứng dụng UML trong quy trình làm phần mềm Như đã trình bày ở trên. UML chỉ thuần túy là một ngôn ngữ mô hình. Các công ty phần mềm khác nhau tuy đều ứng dụng UML nhưng có thể sử dụng các quy trình phát triển khác nhau. 22 .III.

RUP được phát triển bởi công ty Rational Software được sử dụng khá phổ biến. Các nguyên tắc chính của RUP: 1. sơ đồ trạng thái và sơ đồ hành động.Tuân thủ tiến trình (Adapt the process) 2. Một khi các mô hình và tài liệu đặc tả đã hoàn chỉnh.0 phát hành 2005. Stakeholder là những người đưa ra những ý kiến có ảnh hưởng lớn tới tư tưởng thiết kế hệ thống. Sau đây là một số công cụ giúp sử dụng UML trong phát triển hệ thống phần mềm: IV. Quy trình Rational Unified Process (RUP) phát triển phần mềm dựa trên UML IV.1. 3. các bước tiếp theo cần làm song song là xây dựng mô hình use-case và vẽ phác thảo giao diện chương trình. Xuất phát từ ý tưởng ban đầu thuần túy mang tính nghiệp vụ. Tiếp theo xây dựng mô hình sequence system vì thông qua giao diện ta đã biết user tương tác với system như thế nào. Đây là cơ sở để xây dựng sequence detail và hoàn chỉnh mô hình class với các quan hệ đầy đủ.Cân bằng các ưu tiên của stakeholder (Balance stackeholder priorities). Trong quá trình xây dựng các mô hình cần liên tục tiếp xúc với khách hàng để đảm bảo tính chính xác của mô hình.Cộng tác giữa các nhóm (Collaborate across teams) 23 . Giới thiệu về RUP Trong số các quy trình hiện nay. Động cơ phát triển RUP là tìm ra nguyên nhân của các lỗi phần mềm và tìm cách khắc phục chúng thông qua một quy trình. Lịch sử: RUP là sự phối hợp giữa cách tiếp cận công nghệ hướng đối tượng của Rational trong những năm 1980s và 1990s với công nghệ xử lý đối tượng của Ival Jarcobson. Sau đó xây dựng mô hình class ở mức phác thảo. việc coding thực sự chỉ chiếm khoảng 20% tổng số thời gian. Phiên bản mới nhất của RUP là version 7. Như vậy việc lập trình cài đặt chỉ được tiến hành sau khi cac mô hình đã hoàn tất. Theo quan điểm về phân tích thiết kế bằng UML thì việc lập trình rõ ràng không chỉ bắt đầu khi cài đặt các class và các sequence detail bằng một ngôn ngữ lập trình mà thực tế chúng ta đã lập trình ngay từ khi xây dựng mô hình use-case và viết text detail cho nó.2. IV. Đến đây ta đã biết user tương tác với cụ thể đối tượng nào của system và các thông điệp giữa các đối tượng từ mô hình class.Sơ đồ trên cho thấy một trình tự sử dụng các mô hình UML để xây dựng một ứng dụng.

Một biểu đồ khác chi tiết hơn cho ta thấy các các giai đoạn phát triển được tiến hành khi nào và mức độ sử dụng tài nguyên của chúng trong các pha theo các nguyên tắc chung. kiểm thử. có 4 pha: Inception. chuẩn bị nhân lực. vật tư kỹ thuật.3.4. tiếp xúc với khách hàng để nắm bắt ý tưởng và thu thập yêu cầu. cài đặt. tài nguyên của công ty.Tập trung theo dõi chất lượng liên tục (Focus continuously on quality) IV. 24 . Các công việc như thiết kế chi tiết. 5. Elaboration.  Inception: Đây là giai đoạn chuẩn bị.…  Construction: Pha xây dựng hệ thống yêu cầu sử dụng nhiều nhân lực.  Transition: Pha chuyển giao cho khách hàng. Biểu đồ trên cho biết trình tự các pha và lượng tài nguyên sử dụng cho mỗi pha. Vòng đời của phần mềm theo quy trình RUP Trong một vòng đời của phần mềm.…đều được tiến hành trong pha này. các quy trình nghiệp vụ của ứng dụng.Thể hiện kết quả theo quy trình lặp (Demonstrate value iteratively). Construction và Transition. Kết thúc mỗi quy trình cần theo dõi kết quả và kiểm tra chặt chẽ.Nâng cao mức độ trừu tượng (Elevate the level of abstraction) 6.  Elaboration: Sau khi đã thu thập được yêu cầu thì đây là pha thiết kế phác thảo sử dụng các sơ đồ UML để mô hình hóa các yêu cầu.

 Triển khai (Deployment): đưa hệ thống phần mềm vào sử dụng.  Quản trị cấu hình và quản trị thay đổi (Configuration & Change Management): kiểm soát các thay đổi và duy trì sự hợp nhất của các thành phần dự án. xây dựng kế hoạch thực hiện. 25 . tiến hành thử nghiệm hệ thống phần mềm.  Lập trình (Implement): thực hiện các việc xây dựng chương trình bằng ngôn ngữ lập trình.4. Hãng Rational đã xây dựng một hệ thống công cụ như vậy. Các công cụ của RUP Để áp dụng được quy trình phát triển hệ thống phần mềm của Rational thì yêu cầu không thể thiếu là hệ thống các phần mềm công cụ hỗ trợ.  Thử nghiệm (Test): mô tả các tình huống và kịch bản thử nghiệm.  Đảm bảo môi trường: đảm bảo các hạ tầng cần thiết để có thể phát triển được hệ thống.Các giai đoạn công việc của RUP bao gồm:  Mô hình hóa nghiệp vụ (business modeling): mô tả cấu trúc và quy trình nghiệp vụ. IV.  Xác định yêu cầu (requirement): mô tả nghiệp vụ bằng phương pháp “tình huống sử dụng” (use case base method)  Phân tích và thiết kế (analysis & design): mô tả kiến trúc hệ thống thông qua các sơ đồ phân tích thiết kế.  Quản trị dự án: quản lý toàn bộ quá trình làm việc của dự án. mà tiêu biểu và thường dùng nhất là:  Phần mềm Rational Requisite Pro: cho phép phân tích các yêu cầu. xác định các tác nhân của hệ thống cùng những tình huống sử dụng.

triển khai. Bài tập 1. cho phép làm việc theo nhóm. Phần mềm Rational Clear Case: quản trị dự án phân tích thiết kế. Xây dựng mô hình use-case cho hệ thống quản lý việc mượn và trả sách tại thư viện. Hãy mô tả một quy trình ứng dụng UML trong phát triển hệ thống phần mềm. thiết kế. 2. Phần mềm Rational XDE: cho phép vừa xây dựng các mô hình vừa kết sinh mà nguồn chương trình song song với nhau.  Phần mềm Rational Rose: cho phép xây dựng các mô hình phân tích. Hãy tiết text detail và xây dựng mô hình sequence system cho các use-case : “Mượn sách” và “Trả sách”. 26 .

{ 4. 4. các dòng chú thích giúp ta nhanh chóng nhận ra vai trò và ý nghĩa của từng đoạn code.. Từ dấu nhắc gõ lệnh: java c:\ JavaSample\Vidu. 7. System.java Sau lệnh này. 2. I. Giả sử ghi vào thư mục c:\JavaSample. Các chú thích trong chương trình Java được đặt trong cặp /* và */ khi cần chú thích nhiều dòng hoặc để sau cặp // khi chỉ chú thích một dòng.out. tất cả các lệnh nằm trong cặp này đều thuộc phạm vi của lớp Vidu. Dòng 4: Khai báo hàm main. mọi chương trình nếu cần thực thi đều bắt đầu từ hàm main.println("Hello.1 Tìm hiểu mã nguồn một chương trình đơn giản 1. World!”. Để thực hiện chương trình Java trong ví dụ trên. Từ dấu nhắc gõ lệnh: javac c:\JavaSample\Vidu. tên file phải bắt buộc là Vidu giống như tên lớp trong chương trình. 5. Ghi file vừa soạn với tên Vidu. Dòng 6: Câu lệnh in ra màn hình dòng chữ “Hello. Trình thông dịch sẽ tìm hàm main làm điểm khởi phát cho một ứng dụng Java. Trong Java. public class Vidu 3. Thực hiện chương trình Java. Viết và thực hiện một chương trình Java I.class mặc định cũng nằm trong thư mục c:\JavaSample.java. /* Day la chuong trinh vi du*/ 2. Java sẽ sinh ra một file mã bytecode có tên Vidu. } 8.class 27 . Dùng một trình soạn thảo bất kỳ hoặc một IDE Java thì càng tốt để soạn chương trình. 3. Dòng 5 và 7 cũng là đánh dấu mở và đóng cho một khối lệnh thuộc hàm main. Điều này rất quan trọng khi chương trình lớn và gặp lỗi. Cùng với dòng 8 tạo thành một cặp {} dùng để đánh dấu việc mở và đóng cho một khối lệnh. Ở đây.2. public static void main(String[] args) 5. Dòng 3. Trong khi lập trình.java để trình biên dịch Java biết đây là file chứa mã nguồn Java. Dòng 2: Khai báo một lớp có tên Vidu. } Dòng 1: Dòng chú thích trong một chương trình Java. ta cần chú ý viết các dòng chú thích để mô tả về mã nguồn. Tuy nhiên các cặp /* và */ hay được dùng hơn vì các đoạn chú thích này sẽ được tự động đưa vào tài liệu khi ta dùng công cụ javadoc để sinh tài liệu cho mã nguồn. Phần mở rộng cũng bắt buộc là . { 6. chọn Run và gõ vào lệnh “cmd”. trong trường hợp này. Gọi cửa sổ Command Line của Windows: Từ Menu Start. Nhập môn Java I. nếu chương trình không có lỗi cú pháp.Đề tài 2. ta thực hiện theo các bước sau: 1. World!"). Các lệnh trong Java luôn được kết thúc bởi dấu .

 Sử dụng phương thức (method) để thay thế cho hàm và thủ tục.6. Ở đây.Lệnh này sẽ thông dịch file mã bytecode Vidu. World!”. /*Khai bao lop chua ham main*/ public class <tên lớp> { /*Các thuoc tinh cua lop */ ……………………. /*Cac phuong thuc*/ ……………………. ta phải gọi các lệnh này với đường dẫn đầy đủ của nó. khi cài đặt Java ta đã đặt đường dẫn mặc định đến thư mục chứa các lệnh này là C:\Program Files\Java\jdk1. /*Hàm main*/ public static void main(String[] args) { // Các lệnh trong hàm main } } /*Cac lop lien quan khac*/ class A { …………. /*Khai bao thu vien*/ import <tên gói thư viện>. } class B { …………. I. java.  Không được khai báo phương thức. Khai báo gói: 28 .3.4. Một số chú ý khi lập trình Java  Java phân biệt chữ viết hoa và viết thường. hàm hay thủ tục bên ngoài lớp. ta cần chú ý Windows không tự động hiểu các lệnh javac. Tuy nhiên. I. Cấu trúc một chương trình Java /*Khai bao goi*/ package <tên gói>.class và in ra màn hình dòng chữ “Hello.java”  Hàm main trong Java luôn luôn là static  Trong Java tất cả hàm và thủ tục đều phải được đặt trong một lớp cụ thể. } Các thành phần trong một chương trình Java gồm có: 1.  Hàm main phải nằm trong file gọi thực hiện  Tên khai báo phải trùng với tên tệp “Vidu.0_02\bin Trường hợp chưa đặt đường dẫn mặc định.

tất nhiên là bao gồm cả class Vidu.Date” tại dòng số 5. class Vidu sau khi biên dịch sẽ được đặt trong gói my. class Date đã được khai báo import nên không cần khai báo đầy đủ “java. Chỉ có class được gọi thực thi đầu tiên mới cần chứa hàm main. 3.java. 4. } } Ở đây.java. Nếu không làm như vậy. Ví dụ: import my.java. 5. các phần còn lại có thể có hoặc không tùy theo nhu cầu. Java dùng ký từ “*” để ngụ ý việc nhập tất cả các class trong <tên thư viện>.java import my.java. Các kiểu dữ liệu trong Java II. ý nghĩa quan trọng của gói là việc tổ chức một cách logic các lớp vào trong các domain riêng để người phát triển ứng dụng dễ dàng truy cập.util. Khai báo các lớp khác: Thông thường 1 file chương trình Java chúng ta chỉ khai báo 1 class.out. Khai báo hàm main: Không phải tất cả các class trong Java đều chứa hàm main.java. thuộc tính. Tên của gói có chứa các dấu “. khi sử dụng các class nằm trong gói theo <tên thư viện> ta không cần viết đầy đủ tên gói mà chỉ cần viết tên class. Nhập thư viện.Vidu.Vidu”.” chỉ sự bao gồm. chúng ta sẽ rất khó khăn để tìm ra một class để sử dụng.println(“Hôm nay "+date). nó cần truy cập theo đường dẫn gói “my. tất cả các class đều có phần 3. Khai báo này là không bắt buộc với một chương trình Java.util.*. //tạo biến đối tượng thuộc class Date System. hàm thành phần: Các khai báo này sẽ được bàn chi tiết trong mục “Lập trình hướng đối tượng trong Java”. Khi một chương trình Java khác muốn truy cập tới lớp Vidu. II.Date. Khai báo class. Trong hàng ngàn class được Java hỗ trợ trong các gói thư viện. 2. // Nhập tất cả các class có trong gói my. chúng đều được nhóm lại theo chức năng và mục đích sử dụng với tên gói có tính chất gợi ý. Thực ra.Cú pháp: package <tên gói>.1 Các kiểu dữ liệu số nguyên Java có 4 kiểu số nguyên: 29 . Trong chương trình trên. ở đây gói “java” nằm trong gói “my” và class Vidu nằm trong gói “java”. //Khai báo thư viện /*Chương trình in ra ngày tháng hiện hành*/ public class Application { public static void main(String[] args) { Date date = new Date(). Tuy nhiên khi class đó quá phức tạp chúng ta có thể tách ra thành các class khác. Trong số 5 phần trên. // Nhập duy nhất class Vidu trong gói my. Trong trường hợp ứng dụng gồm nhiều class và cần tổ chức các class vào các gói riêng thì ta cần khai báo gói. Cú pháp: import <tên thư viện> Nếu có khai báo này. Sau đây là một chương trình ví dụ sử dụng import: import java.

648 đến 2.036.0/0. II.5 Kiểu chuỗi Java xem chuỗi là một đối tượng. Một biến char sẽ có một giá trị là một ký tự Unicode.6 Chuyển đổi giữa các kiểu số char byte short int long double float 30 .40282347E+38F double 8 bytes Xấp xỉ ±1.854. II.lang.036.0f).483.775.768 đến 32.483.int short long byte 4 bytes 2 bytes 8 bytes 1 byte Từ –2.String.4 Kiểu logic (boolean) Là kiểu dữ liệu chỉ có hai giá trị true và false dùng để xác định kết quả một điều kiện.775.767 Từ –9. Chú ý: kiểu boolean không được thể hiện là 0 và 1.372.807 Từ –128 đến 127 II. Biến đối tượng chuỗi thường được khai báo từ lớp String nằm trong gói java.808 đến9.854.223. II.147.223. 647 Từ –32.  NaN (không là một số = 0.  Số 0.79769313486231570E+308 Số dấu chấm động có thể nhận các giá trị:  Vô cực âm/dương.  Số âm/dương.3 Kiểu ký tự (character) Là kiểu dữ liệu về ký tự.147.2 Các kiểu số thực Java có 2 kiểu số thực dấu chấm động: float 4 bytes Xấp xỉ ±3. II.372.

có thể dùng các ký tự (chữ). short j = 10. //khai báo một chuỗi AudioClip music. con trỏ. III. // ví dụ lớp của AudioClip Khởi động giá trị cho biến Ví dụ về khởi động biến ngay lúc khai báo: byte i = 3. Biến chỉ lưu giá trị địa chỉ đầu của một vùng nhớ được cấp phát cho đối tượng.  Không có khoảng trống giữa tên. ký tự số. Ví dụ khai báo cho từng kiểu biến toán học: byte i. Ở đây cần chú ý rằng khi khởi tạo giá trị cho các kiểu số nên xác định rõ kiểu dữ liệu của giá trị. double z.  Sau ký tự đầu. đối tượng.2 Khai báo biến Các biến trong Java rơi vào hai trường hợp:  Toán học: Các biến có kiểu nguyên thủy của Java đều thuộc dạng này. short j. int k. Ví dụ về khai báo biến kiểu địa chỉ: String strHello. Các biến địa chỉ thường sử dụng để lưu trữ các địa chỉ mảng. float y. int k = 1.25f. long x. Sau khi khai báo.  Không trùng với các từ khoá. char ch. dấu dollard.  Địa chỉ: Các biến đối tượng được lưu ở dạng này. một dấu gạch dưới (_) hay một dấu dollard ($).III. Các giá trị mặc định byte 0 short 0 int 0 31 . float y = 1.45d. biến được cấp phát một vùng nhớ cố định tùy theo kích thước của kiểu dữ liệu của biến đó. double z = 23. char ch = „T‟. ta cần chú ý tuân thủ các điểm sau:  Chỉ bắt đầu bằng một ký tự (chữ). dấu gạch dưới. long x = 1234567L. Khai báo biến và hằng trong Java III. boolean bQuit. boolean bQuit = true. String strHello = “Hello everybody”.1 Quy tắc đặt tên biến Khi khai báo các biến trong chương trình Java.

long 0L; float 0.0f; double 0.0d; char null; boolean false; Các biến dẫn suất null III.3 Biến kiểu mảng Khi cần làm việc với một tập các giá trị có cùng kiểu dữ liệu, ta có thể sử dụng một biến mảng để lưu trữ chúng. Khai báo: Một biến mảng được khai báo theo hai cách:  Sử dụng cặp ngoặc vuông đặt sau tên biến.  Sử dụng cặp ngoặc vuông đặt sau kiểu dữ liệu. Ví dụ: int [] intArray; hoặc int intArray[]; đều cho ta một mảng số nguyên có tên la intArray. Thông thường ta dùng kiểu khai báo thứ nhất để có thể khai báo nhiều biến mảng cùng kiểu dữ liệu: int [] intArray1, intArray2, intArray3; Định vị mảng Sau khi khai báo, bản thân mảng chưa xác định hay chưa được định vị vì chưa được cấp phát vùng nhớ . Do đó, mảng cần được cấp phát vùng nhớ trước khi sử dụng. Dùng từ khoá new để định vị cho một mảng trong vùng nhớ, ví dụ: int IntArray[] = new int[100];//tạo mảng 100pt float floatArray[]; floatArray = new float[10]; //tạo mảng 10 pt Khởi tạo giá trị cho mảng Ta cũng có thể khởi tạo một mảng bằng cách liệt kê các phần tử của nó, ví dụ: int IntArray[] = {1, 2, 3, 4, 5}; char [] charArray = {„a‟, „b‟, „c‟}; IntArray[] = new int[] {1, 2, 3, 4, 5}; Truy cập các phần tử của mảng Các phần tử trong một mảng luôn được đánh số bắt đầu từ số 0. Kiểu dữ liệu của chỉ số là kiểu int. Tuy nhiên nếu dùng kiểu char thì Java sẽ tự động chuyển sang mã ASCII tương ứng. Ví dụ b[„a‟] tương ứng với b[97]. Phần tử đầu tiên là phần tử thứ 0, và phần tử cuối cùng của một mảng có n phần tử là n-1. Các phần tử của mảng được truy cập một cách trực tiếp bằng chỉ số của nó. Ví dụ: int IntArray[] = {1, 2, 3, 4, 5}; int a = IntArray[2];//a=3 int b = IntArray[0];//b=1 Ta có thể gán các giá trị của mảng thông qua truy nhập vào từng phần tử của mảng. Ví dụ: int intList[] = new int[10]; //tạo mảng 10pt intList[0] = 99; //Phần tử thứ 0 (đầu tiên) có giá trị là 99. for (sort i=1; i<10; i++)

32

intList[i] = 1; //các phần tử còn lại bằng 1 Ví dụ: int x, y, k; x = intList[0]; //x=99 y = intList[5]; //y=1 k = intList[y+1]; //k=intList[6]=1 Mảng nhiều chiều: Khai báo mảng 2 chiều: <kiểu phần tử>[][] <tên mảng> = {<danh sách phần tử>}; Ví dụ: int[][] b = {{1,2},{3,4}}; Đây là khai báo và khởi tạo giá trị cho một mạng 2 chiều kích thước 2 x 2. {1,2} là các phần tử của hàng 1; {3,4} là các phần tử trên hàng thứ 2. Hoặc ta có thể khai báo rõ số hàng và số cột của mảng: int b[][] = new int[ 3 ][ 4 ]; Thậm chí ta có thể khai báo một mảng 3 chiều hoặc hơn. int b[][][] = {{{1,2},{3,4}},{{5,6},{7,8}}}; Ta được b[0][0][0] =1; b[0][0][1]=2;b[1][1][1]=8;b[0][1][0]=3; III.4 Hằng số (literal) Là một giá trị không đổi được sử dụng trong chương trình. Hằng số được biểu diễn như chính nó chứ không là một giá trị của biến hay một kết quả của biểu thức. Giá trị của hằng số không thể bị thay đổi. Ví dụ: Pi = 3.1415. Tên của hằng số được đặt tên như tên biến. Cách khai báo hằng cũng tương tự như biến nhưng có dùng thêm từ khóa final: <phạm vi> final <kiểu dữ liệu của hằng> <tên hằng> = <giá trị> Ví dụ: public final String mauda ="vang"; Hằng số có thể là: Hằng số nguyên: Hằng có thể được biểu diễn dưới dạng thập phân, bát phân, thập lục phân. Ví dụ: biểu diễn số 15 dạng int: 15. dạng long: 15L. dạng bát phân: 017. dạng thập lục phân: 0xF. Hằng số thực: Tương tự như hằng số nguyên, để chỉ rõ hằng là float ta thêm vĩ ngữ “ f ” hay “F”, hằng là double ta thêm “d” hay “D”. Hằng Boolean: Một hằng số kiểu boolean có giá trị là true hoặc false. Trong Java, các giá trị 0 và 1 không được dùng thay thế cho false và true như trong C hoặc C++. Hằng ký tự: Là một ký tự đơn giản hay một chuỗi ESCAPE, hằng ký tự được đặt trong hai dấu ngoặc đơn „‟. Các chuỗi ESCAPE: „\b‟ : Xoá lùi. „\n‟ : Xuống dòng. „\t‟ : Tab ngang. 33

„\f‟ : đẩy trang. „\r‟ : dấu enter. „\”‟ : nháy kép. „\’‟ : nháy đơn. „\\‟ : sổ ngược. „uxxxx‟: ký tự unicode. Ví dụ: System.out.println(“Xin chào bạn \n Nguyễn Văn A”); Sẽ in ra màn hình kết quả: Xin chào bạn Nguyễn Văn A Hằng chuỗi ký tự: Một hằng chuỗi ký tự có thể có 0 ký tự (hằng chuỗi rỗng) hay nhiều ký tự. Ví dụ: “A String”, “” //chuỗi rỗng, “dong 1 \t\n dong 2”. III.5 Phạm vi hoạt động của hằng và biến: Khối lệnh Block 1 chứa 2 khối lệnh con Block 2, Block 3.

{ Block 1
{ Block 2 }

{
Block 3

}

}
Biến hay hằng sẽ chỉ có ý nghĩa trong phạm vi khối lệnh mà nó được khai báo.

IV. Các toán tử và biểu thức
IV.1 Các toán tử và thứ tự ưu tiên Các toán tử thường sử dụng: Toán tử Ý nghĩa = Gán != so sánh khác > so sánh lớn hơn < so sánh nhỏ hơn >= lớn hơn hoặc bằng <= nhỏ hơn hoặc bằng + cộng trừ * Nhân / Chia

Ví dụ x=10 x!=5 x>5 x<20 x>=10 x<=10 y=x+1 y=x-1 y=x*3 y=x/3

34

&. *=.% ++ -+= -= *= /= ^ | & ! && || == Lấy phần dư tăng giá trị lên 1 giảm giá trị đi 1 cộng kết hợp phép gán trừ kết hợp phép gán nhân kết hợp phép gán chia kết hợp phép gán phép XOR trên bit phép OR trên bit phép và trên bit Toán tử logic NOT Toán tử logic AND Toán tử logic OR So sánh bằng nhau 10%3 = 1 x++ x-x+=y tương đương x=x+y x-=y tương đương x=x-y x*=y tương đương x=x*y x/=y tương đương x=x/y x^y x|y Thứ tự ưu tiên: ( ). ta cần xác định rõ các số 1 và 100 là các số double.. =. ^. %.  Biểu thức logic chỉ cho ra kết quả là các giá trị true hay false. Ví dụ: (x+3)/(y-2). /. ||. nếu cho giá trị là true thì khối lệnh sẽ được thực hiện. 35 . &&. Để khắc phục tình trạng này.  Biểu thức gán dùng để gán giá trị cho một biến. %=. ta không thu được delta = 0. !=. /=.. |. -. Trong tình huống này. ta cần chú ý tới vấn đề đồng nhất kiểu dữ liệu giữa hai vế để tránh mất thông tin. kết quả là một giá trị số.2 Biểu thức Biểu thức là sự kết hợp các biến số. Khi sử dụng câu lệnh gán kết quả của một biểu thức cho một biến. Ví dụ: Double delta = 0.0d.1 Lệnh if Lệnh if. -=. //khai báo một biến số thực có tên delta delta = 1/ 100.. += IV. *. Lý do là các số 1 và 100 đều được hiểu là các số nguyên và kết quả của phép chia được tự động làm tròn thành một giá trị nguyên trước khi gán cho delta. +. Có 3 loại biểu thức chính là:  Biểu thức số liên kết các biến số. Các lệnh điều khiển rẽ nhánh V. một hằng. Cấu trúc: if <biểu thức boolean> { <khối lệnh>.= =. V. các giá trị bởi các toán tử hoặc có thể là một phép gán giá trị một biểu thức cho một biến số.}: là một phép kiểm tra giá trị của một biểu thức boolean.{. // Gán cho delta kết quả của phép chia 1 cho 100..01 như mong đợi mà là delta =0. delta = 1d/100d. các hằng bằng các phép toán số.

case <giá trị n>: <khối lệnh n>. Cấu trúc: switch <biểu thức>{ case <giá trị 1>: <khối lệnh 1>. khối lệnh sẽ được thực hiện.. case <giá trị 2>: <khối lệnh 2>. } else { System.out.. còn nếu biểu thức boolean sai thì <khối lệnh 2> được thực hiện. còn nếu biểu thức đó sai thì khối lệnh sẽ bị bỏ qua. break.…<giá trị n> phải là các hằng số. Ví dụ: public class dkIfThen { public static void main(String[] args) { int x=1. int y=x-1. Lệnh switch …case Lệnh switch .. int y=x+1. } Một số chú ý khi sử dụng lệnh switch-case: Các giá trị: <giá trị 1>.. break. }}} V. <giá trị 2>. break. 36 . case .: Cho phép chọn nhiều trường hợp xảy ra của giá trị so sánh. if (x<y) { System. if (x<y) { System. default: <khối lệnh default>.. } Nếu biểu thức boolean đúng thì <khối lệnh 1> được thực hiện.println("x>y").out. } }} Dạng 2 của câu lệnh if: if <biểu thức boolean> { <khối lệnh 1>.println("x>y").} Nếu biểu thức boolean đúng.out. } else { <khối lệnh 2>..println("x<y"). break. Ví dụ: public class dkIfThen { public static void main(String[] args) { int x=1. .2.

ta có thể sử dụng một vòng lặp for.println(sum).Nếu không sử dụng lệnh break mỗi khi kết thúc các khối lệnh thì sau khi thực hiện xong khối lệnh. } Bắt đầu với giá trị <khởi tạo> của biến đếm.1.1.out.1. [<bước nhảy>]) { <Khối lệnh>.4. } 37 . các lệnh tiếp theo sẽ được thực hiện. Lưu đồ hoạt động của vòng lặp for như sau: Biểu thức biến điều khiển Biểu thức điều chỉnh theo bước nhảy Biểu thức kiểm tra true false Thực hiện khối lệnh Kết thúc vòng for Ví dụ: tính tổng 1 dãy số thực public class vdFor { public static void main(String[] args) { double accounts[]={1.6}. Cấu trúc lệnh: for([<khởi tạo>]. VI. vòng lặp chấm dứt. Vòng lặp for Khi muốn một khối lệnh được thực hiện với một số lần biết trước. } System. Các lệnh lặp VI.2.i<accounts. Sau mỗi lần thực hiện xong <khối lệnh>. double sum=0. còn nếu là false. <khối lệnh> được thực hiện. [<biểu thức kiểm tra>].i++){ sum+=accounts[i].length. Nếu biểu thức kiểm tra là true thì lại thực hiện khối lệnh. for (int i=0. biến đếm thay đổi giá trị một lượng bằng <bước nhảy> và <biểu thức kiểm tra> được tính lại.

. 38 . ] } VI.}//kết quả là: 4.3.. } Khối lệnh được thực hiện khi <bt boolean> còn có giá trị true.2 Các vòng for có thể được đặt lồng nhau nếu cần Ví dụ: for(int i=0. j++) { [các câu lệnh. ] . } [các câu lệnh. thường là với một số lần không được biết trước.. while Vòng lặp này có ý nghĩa tương tự như vòng lặp while nhưng <khối lệnh> được thực hiện ngay ở vòng đầu tiên mà chưa cần kiểm tra kết quả <biểu thức boolean>. j<5. Lưu đồ thực hiện: Bt boolean false true Các câu lệnh Câu lệnh tiếp theo VI. i<10..2. i++) { [các câu lệnh. Cấu trúc lệnh: while <bt boolean> { <Khối lệnh>. ] for(int j=0. Vòng lặp do. Vòng lặp while Khi một khối lệnh cần được thực hiện. ta có thể sử dụng vòng lặp while. Chú ý: trong khối lệnh phải có câu lệnh có tác dụng ảnh hưởng tới kết quả <bt boolean> để vòng lặp có thể dừng.

x++. System. Lệnh continue Cho phép chương trình bỏ qua vòng hiện tại và nhảy đến vòng tiếp theo. nếu tìm thấy phải thôi duyệt dãy ngay. } } //kết quả là: 55 VI. } lệnh 4. Phép nhảy Trong một số trường hợp. } while (x<11). nếu không sẽ dừng vòng lặp. Ví dụ tính tổng 10 số đầu tiên: public class vdDoWhile { public static void main(String[] args) { int x=1. if <bt boolean 2> 39 . do{ sum+=x. lệnh 2. Vòng lặp này cho thực hiện <khối lệnh> rồi mới kiểm tra <biểu thức boolean>. Ví dụ: while <bt boolean 1>{ lệnh 1. Việc nhảy ra khỏi vòng lặp được thực hiện với từ khoá break hoặc kết thúc vòng hiện tại với lệnh continue. việc thực hiện các vòng lặp đôi khi không theo hết vòng mà có thể dừng hoặc thoát khỏi vòng lặp. Ví dụ: while <bt boolean 1>{ lệnh 1. so sánh các phần tử của dãy với giá trị cần tìm từ phần tử đầu tiên cho đến phần tử cuối cùng. Lệnh break Lệnh này kết thúc ngay vòng lặp trong cùng (nếu có nhiều vòng lồng nhau) chứa nó.Cấu trúc lệnh: do { <khối lệnh>. lệnh 3. } while <biểu thức boolean>.out. sum=0. lệnh 2.println(sum). if <bt boolean 2> break.4. Ví dụ: Tìm một giá trị nào đó trong một dãy 1000 phần tử. Khi thực hiện vòng lặp duyệt dãy. Nếu <biểu thức boolean> có giá trị true thì tiếp tục thực hiện <khối lệnh>.

ta làm theo các bước sau: 1. // Khai báo một biến Scanner có tên là “nhap”.nextInt().util..nextLine(). Tương tự cho các kiểu dữ liệu khác. VII. // Hien thi ket qua nhap tren man hinh System. Lấy giá trị nhập vào: System. Vào dữ liệu từ bàn phím và xuất dữ liệu ra màn hình VII.print("How old are you? ").*/ String name = nhap. // Lay gia trị nhap ho ten System.util. Để đọc 1 từ trong chuỗi nhập vào: String firstName = nhap.*. " + name + ".print("What is your name? ").util.println("Hello.nextInt().print("What is your name? ").out. Next year. int age = nhap. 2.nextLine(). Ví dụ: import java. Khai báo biến thuộc lớp Scanner”. } lệnh 3.out. // Lay gia tri nhap tiep theo System. String name = nhap. Java. you'll be " + (age + 1)).in). Nếu đọc vào một số nguyên: int Tuoi = nhap. Lấy giá trị nhập vào từ bàn phím Để lấy giá trị mà người sử dụng nhập từ bàn phím.1. } lệnh 4. Khi <bt boolean 2> có giá trị true.out. public class InputTest { public static void main(String[] args) { Scanner nhap = new Scanner(System. chương trình sẽ không thực hiện tiếp <lệnh 3> mà quay lại kiểm tra <bt boolean 1>.Scanner nhap = new java.util. continue.Scanner(System. // In ra màn hình một câu hỏi tên /* Khai báo và gán giá trị nhập từ bàn phím cho một biến kiểu String có tên name.{ ……. Lớp Scanner chỉ được hỗ trợ từ phiên bản Java 1.5 và nằm trong gói java. } } 40 . lệnh continue được thực hiện.in).out.next().

out.out. ta đã biết dùng hàm System.out.3f \n".printf(“Hello. System.out.2 Kết xuất dữ liệu ra màn hình Trong các chương trình ví dụ trên.59e+01 Sau đây là ví dụ sử dụng các ký tự định dạng khi xuất dữ liệu ra màn hình.songuyen).printf("He 16 cua 100 duoc viet la: %x \n".printf("He 8 cua 100 duoc viet la: %o \n". }} 41 . Sau đây là bảng các ký tự định dạng: Ký tự định dạng D X O F E A S C B H tx % N Định dạng Số nguyên thập phân Số nguyên hệ 16 Số nguyên hệ 8 Số thực float Số thực float dạng Hexa String Ký tự Boolean Hash code Date and time Ký hiệu phần trăm Xuống dòng % Ví dụ 159 9f 237 15.9 0x1. name. /*In ra ký tự đặc biệt “” */ System.sothuc).printf(“%8.1f”.print("\"Mot tram phan tram\" thi in ra the nao: 100%"). System.print để in dữ liệu ra màn hình.out. public class TestFormat { public static void main(String[] argvs) { double sothuc = 10. /*In ra số nguyên ở hệ cơ số 16*/ System.printf("Ket qua 3 so sau dau phay la %10. Tuy nhiên.09898765. /*In ra số thực chiếm 10 ký tự trên màn hình trong đó phần thập phân chiếm 3 ký tự*/ System. trong một số trường hợp ta cần định dạng dữ liệu xuất ra chẳng hạn như hiển thị một số thực dạng thập phân với độ chính xác nhất định.out. 10/3).songuyen). /*In ra số nguyên ở hệ cơ số 8*/ System.VII. %s. You have %f VND ”.fccdp3 Hello H True 42628b2 Số thực float theo ký pháp cơ số e 1.out. int songuyen =100.money).

6. case 1: System. d) Đoạn mã sau sẽ in ra các số nguyên chẵn từ 2 đến 100 ?: counter = 2.out.print() hay System. } While ( counter < 100 ).1/4! + … + 1/(2k+1)! . } c) Đoạn mã sau sẽ in ra các số nguyên lẻ từ 19 đến 1 ?: for ( x = 19.out. i <= 10. 4.out.out. Viết chương trình tìm số nhỏ nhất trong số các số được nhập vào từ bàn phím. i++ ) { for ( int j = 1. x += 2 ) System.out.println(). 3. } } } 7.out. Các từ cách nhau bởi dấu space. Cho biết số nguyên đầu tiên nhập vào sẽ chính là số các con số được nhập. Tìm các lỗi trong các đoạn chương trình sau: a) For ( x = 100. counter += 2. do { System. Viết chương trình đếm số từ có trong một chuỗi ký tự nhập vào. j <= 5.…nhập từ bàn phím): A = 1 + 1/2! + 1/3! + … + 1/n! B = 1/1! – 1/2! + 1/3! .println( "Even integer" ). Nhập vào một chuỗi họ tên của một người.Lưu ý rằng khi sử dụng các ký tự định dạng ta cần dùng hàm System.….out. 2.printf() thay vì System.out. Ví dụ: nguyen van nam -> Nguyen Van Nam 5.print( '@' ). x++ ) System.println() như thường lệ. 42 . j++ ) System. và .. System. x >= 1.println( "Odd integer" ). k.out. hãy sửa lại các ký tự đầu các từ cho đúng quy định viết hoa và khoảng cách giữa các từ. Đoạn chương trình sau làm gì? public class Printing { public static void main( String args[] ) { for ( int i = 1. Viết chương trình tính giá trị các biểu thức (Giá trị n. Bài tập 1. x >= 1.println( x ).println( counter ). b) Đoạn mã sau sẽ in ra các giá trị chẵn hay lẻ: switch ( value % 2 ) { case 0: System.out. Viết chương trình đếm tần suất xuất hiện của các từ trong một chuỗi nhập từ bàn phím.println( x ).

141. Tính số PI theo công thức sau: In ra 10 giá trị chính xác hơn 3. 43 . Viết chương trình in ra màn hình các mẫu như sau: 9.8.

3 Trừu tượng hóa Quản lý thông tin. Chúng ta sử dụng kỹ thuật hướng đối tượng để ánh xạ những thực thể chúng ta gặp phải trong đời sống thực thành những thực thể tương tự trong máy tính. các dự án phần mềm phân tích và thiết kế theo UML bắt buộc phải sử dụng kỹ thuật OOP để cài đặt thì mới phát huy hiệu quả. Đối với một ngôn ngữ lập trình hỗ trợ OOP thì việc triển khai kỹ thuật lập trình hướng đối tượng sẽ dễ dàng hơn. Thông tin về đối tượng và mối quan hệ giữa chúng thực tế là vô cùng. thuận lợi cho việc sử dụng kế thừa các đối tượng – tính tái sử dụng. các hành vi. Theo cách hiểu như vậy thì mọi nghiệp vụ thực tế suy cho cùng chỉ là việc quản lý các đối tượng. thường là ngôn ngữ OOP. chúng sở hữu các tính chất và thuộc tính riêng. Môi trường này bao gồm một thư viện được thiết kế tốt.1. Chúng ta gọi chúng là những đối tượng. các mối quan hệ của các đối tượng là nhiệm vụ mà lập trình OOP phải làm. Thực tế thì ta không thể viết chương trình hướng đối tượng bằng các ngôn ngữ cấu trúc (như Pascal chẳng hạn) vì các ngôn ngữ này không hỗ trợ cú pháp cài đặt và kỹ thuật biên dịch các đặc tính của hướng đối tượng. cách thức vận động riêng.OOP) I. ta thấy mọi vật đều có vị trí riêng của nó. Do đó. phát triển phần mềm theo kỹ thuật lập trình hướng đối tượng có khả năng giảm thiểu sự lẫn lộn thường xảy ra giữa hệ thống và lĩnh vực ứng dụng. Những ngôn ngữ OOP không chỉ bao gồm cú pháp và một trình biên dịch (compiler) mà còn có một môi trường phát triển toàn diện. I. lập trình viên phải nắm được sự tương ứng giữa các các đối tượng thực tế. từ nghiệp vụ thực tế chúng ta không thể ngay lập tức đem vào cài đặt trong ngôn ngữ OOP mà phải qua một quy trình phân tích và thiết kế theo hướng đối tượng như chúng ta đã thấy qua việc nghiên cứu ngôn ngữ mô hình hóa UML – một ngôn ngữ giúp chúng ta trừu tượng hóa thế giới thực. Đây là một điểm mạnh của OOP và phương pháp trước đây không có được. nếu dùng một ngôn ngữ OOP mà chương trình không theo hướng đối tượng thì cũng không phải là lập trình OOP. Trong khi nếu dùng một ngôn ngữ không hướng đối tượng để viết một chương trình OOP (rất khó khăn) thì cũng có thể gọi là lập trình OOP. OOP là phương thức tư duy mới để giải quyết vấn đề bằng máy tính. Khái niệm lập trình hướng đối tượng (Object-Oriented Programming . Như vậy. Tuy nhiên.2 Cơ sở lý luận của OOP Chúng ta thấy rằng thuật ngữ “hướng đối tượng” có nghĩa là lấy đối tượng làm trung tâm và tất cả nằm trong đối tượng.Đề tài 3. Quan sát thế giới thực. mối quan hệ giữa chúng và sự hỗ trợ của ngôn ngữ để cài đặt chúng vào máy tính. I. Hơn nữa. Vậy làm thế nào để đưa chúng vào máy tính? Câu trả lời là chúng ta cần một quá trình trừu tượng hóa. Ngôn ngữ OOP cung cấp đầy đủ phương tiện để thực hiện điều này. Để đạt kết quả. Khái niệm OOP Lập trình hướng đối tượng là sự cài đặt một chương trình theo hướng đối tượng bằng các ngôn ngữ lập trình. 44 . Lập trình hướng đối tượng trong Java I. khai thác thông tin cũng như các mối quan hệ từ chúng hoặc thay đổi trạng thái của chúng.

Cũng là một sinh viên nhưng nếu chẳng may anh ta bị ốm nằm viện. mô hình này đại diện cho tất cả sinh viên và là khuôn mẫu để tạo ra bất kỳ sinh viên nào khác. các thông tin khác về sinh viên – cũng là một con người – như chiều cao. Trong ví dụ trên. Các lớp đối tượng trong chương trình . Khi quan tâm tới giá trị của các thuộc tính. Một hệ thống quản lý bệnh nhân tất nhiên không thể bỏ qua các thông tin về nhóm máu. Qua đây. Tóm lại. huyết áp. anh ta được quản lý như một bệnh nhân.…chúng ta không cần quan tâm. Một hệ thống quản lý sinh viên có thể chỉ cần quan tâm tới: Họ và tên. chúng ta có một mô hình trừu tượng hóa của một sinh viên: Sinh viên Họ và tên Ngày sinh Tên lớp Địa chỉ Điểm môn học Thay đổi lớp Thay đổi nơi ở Điểm quan trọng là sau khi trừu tượng hóa từ một lớp các sinh viên (tất cả các sinh viên trong phạm vi quản lý). lớp học. địa chỉ nơi ở.Classes Trừu tượng hóa Thế giới thực = Các đối tượng + Các mối quan hệ   Tóm lại: Các thực thể tồn tại trong thế giới thực được mô hình hóa thành các lớp đối tượng. điểm các môn học. một anh sinh viên bất kỳ có thể có hành vi “xin đổi lớp học” hoặc “đổi địa chỉ nơi ở” làm cho giá trị các thuộc tính “lớp học”.Giả sử đối tượng quản lý là một sinh viên. 45 . Các mối quan hệ giữa các thực thể trong thế giới thực được mô hình hóa bằng các mối quan hệ giữa các lớp đối tượng. cân nặng. chúng ta có một câu hỏi: Cái gì làm cho dữ liệu này biến đối? Câu trả lời là chính hành vi của đối tượng làm cho thuộc tính của chúng bị thay đổi. Quá trình xác định các hành vi của đối tượng phục vụ cho nghiệp vụ quản lý cũng là một quá trình trừu tượng hóa hành vi. ngày sinh. Trong khi đó. cân nặng. nhóm máu. ta cũng rút ra nhận xét rằng quá trình trừu tượng hóa tùy theo yêu cầu nghiệp vụ sẽ cho kết quả khác nhau.…và tất nhiên là cũng có các mô hình hành vi khác. Ở đây ta không quan tâm tới giá trị cụ thể của các thuộc tính này. Một quá trình suy luận như vậy là một quá trình trừu tượng hóa dữ liệu. “địa chỉ nơi ở” bị thay đổi.

Tách các class phức tạp 46 . Không sử dụng quá nhiều kiểu dữ liệu cơ bản trong 1 lớp Không phải thuộc tính nào cũng cần mutator và accesor: Mỗi thuộc tính bao giờ cũng có một phương thức thiết đặt giá trị cho nó gọi là mutator (tiền tố set) và một phương thức lấy ra giá trị của nó gọi là accesor (tiền tố get). Hành vi được cài đặt thông qua mã lệnh Java bởi các phương thức. Mỗi HoaDonThanhToanNhanh thừa kế các thuộc tính và phương thức của HoaDon và có thêm các thuộc tính. private. Tính đóng gói trong Java II. II.một sự mô hình hóa một lớp đối tượng trong thực tế. Thuộc tính được cài đặt thông qua mã lệnh Java bằng các biến thành phần trong lớp.1 Khái niệm tính đóng gói Tính đóng gói thể hiện bởi việc thuộc tính mô tả đối tượng và hành vi của đối tượng được gắn chặt với nhau.2 Mối quan hệ giữa các class Các class trong chương trình có thể quan hệ với nhau theo 1 trong 3 dạng:  Phụ thuộc (Dependence): Class A có quan hệ phụ thuộc với class B nếu phương thức của class A có sử dụng đối tượng thuộc class B. Ví dụ: Trong hệ thống bán hàng chúng ta có:  class DanhMucMatHang  class TaiKhoan  class HoaDon  class HoaDonThanhToanNhanh Mỗi HoaDon bao gồm 1 DanhMucMatHang: Quan hệ aggregation. hành vi làm thay đổi trạng thái đối tượng thông qua việc thay đổi giá trị các thuộc tính.  Thừa kế (inheritance): Class B gọi là thừa kế class A nếu class B có các phương thức và thuộc tính của class A.  Bao gồm (Aggregation): Class A có quan hệ bao gồm với class B nếu đối tượng của class A chứa đối tượng của class B. Thông tin và hành vi đối tượng được bảo vệ bằng các cấp độ truy cập: public.3 Một số gợi ý khi thiết kế class Khai báo dữ liệu private: Điều này tránh việc truy cập tùy ý từ bên ngoài lớp Khởi tạo cho dữ liệu: Các thuộc tính nên được khởi tạo bằng các phương thức constructor khi một đối tượng mới được tạo ra. Cấp độ public cho phép sự truy cập từ bên ngoài lớp trong khi private chỉ cho phép nội bộ lớp truy cập. Thuộc tính thể hiện trạng thái đối tượng. ngoài ra class B còn định nghĩa các phương thức và thuộc tính khác của riêng nó. object = attributes (các thuộc tính) + operations(các hành vi) + name (tên định danh) Như vậy tính đóng gói thể hiện việc chuyển mô hình đối tượng thực tế thành các lớp trong Java.II. Đối tượng được sinh ra bởi class . Khi một HoaDon được tạo ra. nó cần truy cập đến class TaiKhoan để kiểm tra tình trạng thẻ tín dụng: Quan hệ dependence. II. phương thức khác: Quan hệ inheritance.

text java. Cung cấp các lớp cơ bản cho các dịch vụ in ấn qua mạng. IV. Hỗ trợ các lớp để thao tác và thuật toán với các số nguyên lớn BigInteger và BigDecimal. Cung cấp các giao diện và các lớp cho việc giải quyết các vấn đề về xử lý các sự kiện trên các thành phần giao diện AWT. 47 . Sử dụng các Class xây dựng sẵn trong thư viện Java hỗ trợ cho lập trình viên một thư viện phong phú các lớp đối tượng đã được xây dựng và thiết kế cẩn thận.net java.event java.print Hỗ trợ các class cần thiết cho việc tạo ra các Applet và giao tiếp giữa Applet với môi trường ngữ cảnh của nó.Đặt tên phương thức và thuộc tính phản ánh theo tính chất và nghiệp vụ của nó.beans java. dates.awt. Hỗ trợ cho các thao tác vào / ra dữ liệu trên hệ thống file. Cung cấp các hàm API cho việc truy cập vào dữ liệu trong một nguồn dữ liệu – thường là các CSDL quan hệ.awt. Cung cấp các lớp nền tảng để thiết kế ngôn ngữ lập trình Java. Chứa các lớp liên quan tới việc phát triển các thành phần (beans) dựa trên kiến trúc của Java. Hỗ trợ các lớp và giao diện cho các thao tác mã hóa dữ liệu. Cung cấp các lớp cho việc cài đặt các ứng dụng mạng.applet java. ngày tháng.font java. Chứa các lớp dùng để tạo ra các giao diện người dùng và cho các thao tác vẽ các hình đồ họa và ảnh.rmi java.image java. numbers và các thông điệp. Cung cấp các lớp tạo và hiệu chỉnh hình ảnh. Hỗ trợ các giao diện và lớp liên quan đến font chữ.net javax.awt.color java.2/docs/api/overview-summary.awt.html ) Các gói thường dùng trong Java 2 SE java. Cung cấp các lớp và giao diện cho việc quản lý text.print java. Cung cấp các lớp cho không gian màu. Cung cấp các lớp cho lập trình mạng.lang java.io java.util javax. Cung cấp các lớp và giao diện cho việc xử lý các vấn đề an ninh và bảo mật trong Java. Cung cấp các gói cho lập trình RMI – Remote Method Invocation. Lập trình viên chỉ cần biết cách lấy chúng ra và sử dụng chúng theo kịch bản của ứng dụng. Cung cấp các lớp và giao diện cho mục đích in ấn.crypto javax. Các gói thư viện quan trọng của Java 2 bao gồm: (tham khảo chi tiết tại: http://java.….awt.com/j2se/1.sun.sql java. Chứa đựng các lớp tiện ích thuộc nhiều loại khác nhau như sinh số ngẫu nhiên.4.math java.security java.awt java.

Xác định rằng myDate là một đối tượng thực sự thuộc class Date.swing. Khai báo: Date myDate. Cung cấp một tập các thành phần được chấp nhận trên hầu hết các hệ thống máy tính. myDate chưa được cấp phát vùng nhớ. Hỗ trợ cho các sự kiện kích hoạt bởi các thành phần của Swing. Date() là phương thức contructor của class Date.getMonth()). không được khởi tạo đối tượng của lớp này. Xác định cho ta một biến đối tượng Date nhưng không cho ta một đối tượng Date thực sự vì trong thực tế. mặc định là public.1 Cấu trúc của class [<Cách truy xuất>] class <tên lớp> [extends <tên lớp cha>] [implements <tên giao diện>]{ <các thành phần của lớp>. // In ra tháng hiện tại V.swing. Các lớp trừu tượng được thiết kế chỉ cho mục đích kế thừa. Câu lệnh: myDate = new Date().parsers Cung cấp các hàm API cho việc truy cập dữ liệu phía server.out. Xây dựng Class trong Java Cài đặt các class là công việc thường xuyên của lập trình viên Java. final: Không cho phép kế thừa.sql javax. Các vấn đề của công việc thiết kế một lớp bằng ngôn ngữ Java sẽ được đề cập dưới đây. nếu <cách truy xuất > là public thì tên lớp phải trùng với tên file chứa lớp.swing javax.javax.event javax. System. <tên lớp cha>: Tên của lớp cha mà lớp hiện tại thừa kế.swing. Nếu <cách truy xuất> không được xác định.table javax.swing. V. Một đối tượng luôn được tạo ra từ một constructor của lớp đó.xml.JTree. 48 .tree javax. Hỗ trợ các lớp cho việc xử lý các tài liệu XML. Cung cấp các lớp và giao diện làm việc với cây javax.println(myDate. abstract: Lớp trừu tượng. } Ta sẽ lần lượt xem xét từng thành phần: <Cách truy xuất>: public: Có thể truy cập lớp từ các lớp khác. ta có thể áp dụng các phương thức và thuộc tính của class Date cho myDate. Sau đây là hướng dẫn ví dụ về sử dụng lớp Date có sẵn trong thư viện của Java: Khai báo biến đối tượng với toán tử new Date myDate = new Date(). <tên lớp>: Tên của lớp. Cung cấp các lớp và giao diện làm việc với bảng.

Là hằng số của lớp Math. cố định có ở mọi đối tượng. Ta sẽ lần lượt xem xét tới các thành phần này. Hơn nữa. Trong khi đó các hằng thường luôn được khai báo là public vì chúng được dùng chung và không thể bị thay đổi do từ khóa final (hằng). ta có thể không cần khởi tạo đối tượng mà trực tiếp thông qua tên lớp: SinhVien.  protected: Chỉ được truy cập trong lớp đó và các lớp kế thừa. Ví dụ: public int Tuoi. ví dụ gán Tuoi của sinh viên này bằng 21: Sv. <các thành phần của lớp>: đây là phần thân của lớp chứa các định nghĩa cho các thuộc tính và các phương thức thành phần. Biến có phạm vi lớp (biến tĩnh): Đây là biến có phạm vi tồn tại trong mọi đối tượng của lớp được tạo ra trong chương trình đang chạy. V. Đây có thể là một danh sách các giao diện phân tách bởi dấu “. Ví dụ: 49 .<tên giao diện>: Tên của giao diện được cài đặt tại lớp. Khi khai báo một biến có phạm vi lớp. Truy cập vào biến Tuoi như sau: sv. Giá trị của biến được dùng chung giữa các đối tượng. Biến có phạm vi đối tượng: Đây là biến tồn tại cùng với sự tồn tại của đối tượng.2 Các thuộc tính thành phần: Khai báo thuộc tính chính là việc khai báo các biến. Muốn truy cập vào biến. Khi truy cập. trước hết phải khởi tạo một đối tượng thuộc lớp. trong khi các hằng static lại rất hay được dùng.MaSo = 10. private String HoVaTen. SinhVien sv = new SinhVien(20. Cách truy cập biến rất đơn giản. // Mọi sinh viên đều có màu da là “Vang” hoặc khái báo hằng số PI: public static final double PI = 3. ta sẽ cài đặt chúng như là các hằng static. Ví dụ: public static final String MauDa = “Vang”. các biến thông thường có phạm vi private.Tuoi=21. Khi khai báo trong lớp chúng thường được xác định phạm vi hoạt động là một trong các dạng:  public: Biến có thể truy cập ở bất cứ lớp nào.Tuoi. phụ thuộc vào biến thuộc dạng nào trong 2 dạng sau: 1. Khi truy cập ta chỉ cần gọi: Math. Mặc định thì phạm vi truy cập của biến là public.14159265358979323846. các lớp đối tượng thường có các thuộc tính chung.PI Chú ý: Các biến rất ít khi được khai báo là public vì có thể thay đổi giá trị của nó bên ngoài lớp nên khó quản lý. khi chúng đã không phụ thuộc vào một đối tượng cụ thể nào thì ta cũng không cần khởi tạo một đối tượng để truy cập. Các biến có phạm vi lớp rất ít khi được sử dụng. Biến this Biến this là biến đối tượng của lớp tồn tại ngầm trong mỗi lớp. Thường dùng biến this để truy cập đến các thuộc tính của lớp bị khai báo trùng trong phạm vi các phương thức của lớp.”Nguyen Van A”). 2.  private: Chỉ được truy cập trong chính lớp đó. Do đó. Lý do là trong thực tế. ta cần thêm từ khóa static như ví dụ sau: public static int MaSo.”.

int num2) { if(num1>num2) 50 . khi kết thúc các luồng xử lý trong phương thức nhất thiết phải có câu lệnh return để trả về một giá trị thuộc kiểu đó. < Cách cập nhật>  static: phương thức tác động không phụ thuộc vào các đối tượng cụ thể.  Nếu không khai rõ cách truy xuất. Phương thức này sẽ được phát triển trong các lớp là dẫn xuất của lớp chứa nó.out.  protected: chỉ các lớp là dẫn xuất của lớp chứa phương này mới truy xuất được nó. public static int max(int num1.. tức là nó không có phần thân. //in bien number = 20 System.3 Các phương thức thành phần Phương thức thành phần là sự cài đặt các hành vi của đối tượng.: là các kiểu dữ liệu mà phương thức trả về.  native: là phương thức được viết bằng ngôn ngữ khác java. Cú pháp khai báo một phương thức trong lớp như sau: [<Cách truy xuất> <cách cập nhật>] <Kiểu giá trị trả về> <Tên phương thức>([<danh sách biến hình thức>]) [<mệnh đề throws>] { <Nội dung của phương thức>. . Lớp có chứa phương thức abstract cũng phải được khai báo abstract.println(this.number). public void PrintNumber() { int number =20.  abstract: phương thức đơn giản nhất. Các phương thức khai báo chồng ở lớp dẫn xuất phải có mức độ truy cập mạnh hơn hoặc giống với mức độ truy cập ở lớp cha. Khi xác định kiểu giá trị trả về.  final: phương thức này được bảo vệ không cho các lớp dẫn xuất khai báo và cài đặt lại. không cài đặt gì ở trong lớp khai báo nó.public class TestThis { private int number = 10. // khai báo trùng với biến của lớp System. float.. void: phương thức không trả về giá trị. char. } <Cách truy xuất>:  private: phương thức này chỉ được truy xuất bên trong lớp chứa nó.out.  public: có thể truy xuất từ bất kỳ lớp bên ngoài nào.//in bien number =10 } } V. các phương thức sẽ có cách truy xuất mặc định là public.println(number). nó có thể được gọi mà không cần khởi tạo đối tượng của lớp.  synchronyzed: đảm bảo dữ liệu không bị sai lạc khi cùng một lúc 2 phương thức truy cập cùng một dữ liệu. <Kiểu giá trị trả về>: integer. String.

đối tượng được tạo ra bằng phương thức khởi tạo mặc định với các giá trị mặc định của các thuộc tính. Phương thức khởi tạo có cùng tên với tên lớp và không có kiểu dữ liệu trả về. việc gọi phương thức là câu lệnh.println(max(3.println("Hello!"). V. việc gọi phương thức thường được xử lý như một giá trị. Constructor không được kế thừa. Vấn đề sử dụng phương thức khởi tạo của lớp cha trong các lớp dẫn xuất sẽ bàn trong phần “Tính thừa kế” Phương thức hủy: Trái với phương thức khởi tạo. Khi không khai báo phương thức khởi tạo. V. 5)). việc gọi hàm main() đương nhiên là diễn ra bên ngoài lớp nên nó cũng cần có mức độ truy cập là public. Các chú ý khi truyền tham số cho phương thức:  Các phương thức không thể làm thay đổi giá trị của các tham số có kiểu nguyên thủy  Phương thức có thể làm thay đổi trạng thái của tham số kiểu đối tượng  Phương thức không thể làm cho tham số đối tượng tham chiếu tới một đối tượng mới. Ví dụ: int larger = max(3. } Về <mệnh đề throws> chúng ta sẽ xem xét kỹ trong phần xử lý ngoại lệ. lập trình viên không cần quan tâm. Vì nó được gọi khi chưa có đối tượng nào được tạo ra nên nó luôn được khai báo là static. 5). Mỗi lớp có thể có 1 hoặc nhiều phương thức khởi tạo. Gọi một phương thức: Có 2 cách gọi phương thức: Nếu phương thức trả về giá trị. hoặc ta có thể in giá trị trả về của cuộc gọi phương thức: System. else return num2. trong Java công việc này được làm tự động.6 Các hàm và phương thức đặc biệt Phương thức khởi tạo: Phương thức khởi tạo (constructor) dùng để khởi tạo một đối tượng của lớp và đặt trạng thái ban đầu cho đối tượng bằng cách xác định giá trị cho các thuộc tính của lớp. Ví dụ phương thức println() trả về void: System. Tuy nhiên. Trong trường hợp cần thiết ta có thể khai báo phương thức hủy theo cú pháp: protected void finalize() { // Body of Method } Hàm main() Đây là một hàm đặc biệt được cài đặt trong lớp được gọi thực thi đầu tiên trong chương trình.  Các tham số có kiểu đối tượng được truyền theo kiểu tham chiếu. 51 .out. Nếu phương thức trả về void. nó chỉ được định nghĩa cho chính lớp cha.return num1.4 Gọi và truyền tham số cho phương thức  Các tham số kiểu cơ bản được truyền theo kiểu tham trị.out. phương thức hủy được gọi khi đối tượng được giải phóng. Hơn nữa. Hàm main() thường không trả về giá trị nào nên kiểu giá trị trả về của nó là void.

}. kiểu giá trị trả về cũng được xem như một yếu tố để phân biệt các phương thức.double dtk) { super(t. } // Hàm main public static void main(String[] argvs) { // Truy cập vào biến lớp không cần khởi tạo đối tượng SinhVien. // biến lớp // Phương thức khởi tạo public SinhVien(int t.5. V.String ht) { Tuoi=t.MaSo). Điều này gọi là khai báo chồng phương thức.MaSo=10. } // Phương thức hiển thị tên và tuổi của một người public String toString(){ return HoVaTen + ". MaSo của sinh viên này sẽ là 10 SinhVien k = new SinhVien(23.print(k.String l. Từ phiên bản Java 1. System.} Sau đó. HoVaTen=ht.7. // Khởi tạo một đối tượng sinh viên."Nguyen Thi Mai". protected String HoVaTen." + String. private double DiemTongKet. //hằng số // Phương thức khởi tạo public People(int t."Letio3".ht). Sau đây là chương trình ví dụ về xây dựng các class trong Java: abstract class People // Lớp trừu tượng { protected int Tuoi. ta có một lớp SinhVien kế thừa từ lớp People trên: public class SinhVien extends People { private String Lop.Hàm main() có một tham số là một mảng các chuỗi chứa nội dung các tham số dòng lệnh.7 Khai báo chồng các phương thức Các phương thức trong cùng một lớp có thể có cùng tên nhưng nhất định số lượng các tham số hoặc kiểu của chúng phải khác nhau.out. 52 .String ht.15). // Gọi phương thức khởi tạo của lớp cha cho các thuộc tính kế thừa // Các thuộc tính không kế thừa được gán tường minh Lop = l. public static int MaSo. public static final String MauDa=”Vang”. DiemTongKet=dtk.valueOf(Tuoi).

. static class StaticNestedClass { // Lớp lồ ng tinh ̃ ."Letio3". Vì giới hạn này nên lớp lồng tĩnh ít được dùng .8.print(k. Có hai kiểu lớp lồng : tĩnh và phi tĩnh . void display_x() { System."Pham Anh Thu". việc khởi tạo một đối tượng thuộc lớp People sẽ bị báo lỗi do lớp này là lớp trừu tượng. Lớp như vâ ̣y go ̣i là lớp lồ ng (Nested Class) và được cài đặt như sau : class EnclosingClass{ // Lớp bao bên ngoài . Lớp lồng tĩnh (static nested class) đươ ̣c bổ sung từ khoá static . Hầu hết các lớp lồng là lớp nô ̣i bô ̣. } } Lớp lồ ng chỉ đươ ̣c biế t bên trong phạm vi của lớp bao bên ngoài . Mô ̣t lớp lồ ng c ó quyề n truy câ ̣p đế n các thành viên của lớp bao bên ngoài . lớp bao không thể truy xuấ t các thành phần của lớp lồ ng. Nó không thể tham chiếu trực tiế p đế n biế n hay phương thức đố i tươ ̣ng đươ ̣c đinh nghia trong lớp bao. People p = new People(20.toString()).15). // Báo lỗi dòng này } } Trong chương trình trên.SinhVien. Tuy nhiên .. V.MaSo=11.8 Lớp lồng nhau – lớp nội Có thể định nghĩa một lớp bên trong một lớp khác . Chúng ta sẽ trở lại vấn đề này trong phần “Tính kế thừa”. System.display_x(). 53 . // Khởi tạo một đối tượng sinh viên. mà chỉ dùng chúng ̣ ̃ thông qua đố i tươ ̣ng. Trình biên dịch Java sẽ báo lỗi nếu mô ̣t đoa ̣n mã bấ t kỳ của lớp bên ngoài truy cập trực tiế p lớp lồ ng.. } class InnerClass { // Lớp lồ ng phi tinh hay lớp nô ̣i bô ̣ ̃ ... Lớp lồng phi tĩnh (nonstatic nested class ) không bổ sung từ khoá static .out.. inner. Nó có thể truy cập trực tiếp đến các biến và phương thức đối tượng. class Outer { int outer_x = 100.out. MaSo của sinh viên này sẽ là 11 SinhVien k1 = new SinhVien(20. void test() { Inner inner = new Inner().println(“display : outer_x = “ + outer_x). còn đươ ̣c go ̣i là lớp nô ̣i bô ̣ (inner class). } class Inner { // có thể truy xuấ t trực tiế p biế n đố i tươ ̣ng của lớp Outer int inner_y = 10."Pham Anh Hoa"). thâ ̣m chí nế u chúng được khai báo private .

addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent event) { System.println(“display : inner_y = “ + inner_y). } 54 . trong phần này chúng ta sẽ xem xét một ví dụ về quản lý nhân sự tại một công ty. khi xử lý các sự kiện.exit(0).} } void display_y() { // không thể truy xuất biến đối tượng của lớp Inner System.util. Nó được khai báo chồng 2 phương thức của WindowAdapter. int month.test(). int year. GregorianCalendar calendar = new GregorianCalendar(year.1 Sự kế thừa các thuộc tính và phương thức Giả sử trong công ty.GregorianCalendar.out.Date. day). Luong = s. // GregorianCalendar coi 0 là Tháng 1 NgayBatDau = calendar. VI. double s. int day) { HoVaTen = n. // Error } } class InnerClassDemo { public static void main(String args[]) { Outer outer = new Outer(). VI. tức là không có tên. import java. } } Trong Java có sử dụng một kỹ thuật cài đặt lớp nội nặc danh. ta có một lớp nặc danh kế thừa từ lớp WindowAdapter.} } ).util. month . Tính kế thừa trong Java Để theo dõi tính kế thừa trong Java được cài đặt như thế nào. outer. Ví dụ: frame. Lớp Employee được định nghĩa như sau: import java. đội ngũ quản lý (managers) được đối xử khác với nhân viên (employees) bình thường. } public void windowIconified(WindowEvent e) {System. class Employee { // Phương thức khởi tạo public Employee(String n.1.exit(0).getTime(). Ở đây.

Lớp Manager có thêm thuộc tính TienThuong và phương thức để thiết đặt giá trị cho nó: class Manager extends Employee { . với Employee chỉ được trả lương theo một hợp đồng có sẵn trong khi Manager ngoài lương ra còn được hưởng một khoản tiền thưởng. Chúng ta sẽ thiết kế một lớp Manager nhưng kế thừa lại những gì đã viết ở lớp Employee. lớp kế thừa còn được gọi là lớp dẫn xuất. Các lớp dẫn xuất thường được cài đặt nhiều tính năng hơn lớp cha. private double Luong. Lớp đang tồn tại còn được gọi là lớp cha.. class Manager extends Employee { //Các thuộc tính và phương thức bổ sung } Từ khóa extends xác định rằng chúng ta đang tạo ra một lớp mới được dẫn xuất từ một lớp đang tồn tại. } //phương thức lấy ngày bắt đầu làm việc public Date getNgayBatDau() { return NgayBatDau. lớp con. Tuy nhiên. supperclass. } // Phương thức tăng lương public void raiseSalary(double PhanTram) { double PhanTang = Luong * PhanTram / 100.. Luong += PhanTang. hoặc lớp cơ sở (base class). private Date NgayBatDau. } // Các thuộc tính thành phần private String HoVaTen. } // Phương thức lấy lương public double getLuong() { return Luong. } Ta thấy rằng cả Manager và Employee đều có những điểm chung về mặt quản lý như họ cùng được trả lương. public void setTienThuong(double b) { 55 . Đây chính là ngữ cảnh tốt để cài đặt tính kế thừa.// Phương thức lấy họ tên public String getHoVaTen() { return HoVaTen.

ta cần định nghĩa một phương thức mới trong lớp Manager đè lên phương thức cũ: class Manager extends Employee { . } private double TienThuong. // vẫn không thực hiện return LuongCoBan + TienThuong. ta có thể gọi: boss. Đến đây chúng ta nghĩ rằng Luong phải được truy cập thông qua một cơ chế public khác là phương thức getLuong() được định nghĩa public trong Employee. Tương tự như thế. } . Nếu ta có một đối tượng Manager có tên boss. ta đặt các thuộc tính và phương thức phổ biến vào các lớp cha.. Luong và NgayBatDau cũng được kế thừa. Thuộc tính Luong trong Employee được khai báo là private nên chỉ các phương thức trong lớp Employee mới được phép truy cập. Tuy nhiên. getNgayBatDau() đối với các đối tượng của lớp Manager vì chúng được tự động kế thừa từ lớp Employee. } 56 . public double getLuong() { . Tất nhiên là đối tượng của lớp Emplyee không thể gọi phương thức setTienThuong() vì nó không phải là phương thức được định nghĩa trong lớp Employee. Ở đây.. Theo lý thuyết.TienThuong = b. Lớp Manager có 4 thuộc tính là HoVaTen.. NgayBatDau và TienThuong. Tuy nhiên.setTienThuong(10000). Luong.. getLuong(). } Việc sử dụng các thuộc tính và phương thức này không có gì đặc biệt. } Chúng ta có thể nghĩ việc cài đặt cho phương thức mới này rất đơn giản như: public double getLuong() { return Luong + TienThuong. // Không thực hiện } Tuy nhiên nó không thực hiện. Đến đây ta có thể rút ra rằng khi thiết kế các lớp trong Java. phương thức getLuong() đối với lớp Manager phải là tổng của Luong và TienThuong. Tuy nhiên điều này có thể cho phép tất cả các lớp dẫn xuất từ Employee thay đổi giá trị các thuộc tính này làm tính đóng gói của OOP bị phá vỡ. public double getLuong() { double LuongCoBan = getLuong(). các thuộc tính HoVaTen. một số phương thức của lớp cha có thể không còn phù hợp ở lớp con. lớp con chỉ việc khai báo thêm các thuộc tính và phương thức đặc biệt.. chúng ta có thể sử dụng các phương thức getHoVaTen(). Lý do là vì sự truy cập vào Luong ở đây là không hợp lệ. Do đó.. việc xác định cho các thuộc tính lớp Employee cấp độ truy cập là protected có vẻ là hợp lý.

Để gọi được phương thức getLuong() của lớp Employee. int month. } // Phương thức tính lương public double getLuong() { double LuongCoBan = super. ta đã có một lớp Manager được định nghĩa đúng đắn: class Manager extends Employee { // Phương thức khởi tạo public Manager(String n. int month. month. các phương thức khởi tạo không được tự động kế thừa cho lớp con. // OK return LuongCoBan + TienThuong. TienThuong = 0. int year. int day) { super(n. Lý do là phương thức getLuong() lúc này được coi là chính phương thức getLuong() của lớp Manager nên nó không có tác dụng. super(n. } Ở đây. } private double TienThuong. Tuy nhiên ta có thể sử dụng phương thức khởi tạo của lớp cha để khởi tạo giá trị cho các thuộc tính được kế thừa ở lớp con: public Manager(String n. year. } Nếu không cho phép lớp con kế thừa một phương thức của lớp cha. TienThuong = 0. day). } //Phương thức đặt tiền thưởng public void setTienThuong(double b) { TienThuong = b. thay cho việc gọi constructor của Employee với 5 tham số n. s. Đến đây. s. year. public double getLuong() { double LuongCoBan = super. ta dùng từ khóa final khi khai báo phương thức. month. } 57 . ta dùng từ khóa super để chỉ lớp cha. year. day). s.Tuy nhiên. đoạn mã này cũng chưa thực hiện được. month và day. // OK return LuongCoBan + TienThuong.2 Sự kế thừa đối với các constructor Như đã đề cập. month. Lưu ý là lệnh gọi super phải là lệnh đầu tiên trong phương thức constructor ở lớp con. double s. double s.getLuong(). day). int year. year. s. VI. int day) { super(n.getLuong().

Trong khi chúng ta cài đặt tính chất thừa kế của OOP. Trường hợp ngược lại là không thể. 12. 10. đối tượng lớp con không thể được gán tham chiếu tới một đối tượng lớp cha nhưng có thể chuyển kiểu sang lớp cha. thậm chí là cùng danh sách tham số.setTienThuong(5000). Ta có thể gán tham chiếu một đối tượng của lớp con cho một đối tượng của lớp cha. 15). cơ sở của tính đa hình cũng đã được cài đặt. Đây chính là thể hiện tính đa hình của đối tượng. 1). Manager boss = new Manager ("Nguyen Tan Minh". Manager boss1 = new Manager ("Nguyen Tan Phat". boss. boss = me.VII. Nếu khi lập trình ta viết: you = boss. VII. 1). 15).setTienThuong(2000). Một đối tượng của lớp cha có thể được gán tham chiếu tới bất kỳ lớp con nào dẫn xuất từ nó nhưng không ép kiểu sang lớp con được. Employee[] staff = managers. 50000.// Không được Lý do là việc chuyển kiểu chỉ xảy ra lúc chương trình chạy nên khi biên dịch “you” vẫn là một đối tượng Employee. 81000.2 Sự ràng buộc động –Dynamic Binding Xét ví dụ sau: // Khai báo một đối tượng Manager Manager boss = new Manager("Phan Thanh Ha". 1987. VII. 2000. // Cha không chuyển kiểu sang con được Thậm chí một mảng các đối tượng Employee có thể được gán cho một mảng các đối tượng Manager mà không cần chuyển kiểu: Manager[] managers = new Manager[10]. // Khai báo một mảng 3 đối tượng Employee Employee[] staff = new Employee[3]. sự chuyển đổi này chỉ diễn ra trong thời gian chạy chương trình. // Chuyển kiểu OK boss1 = (Manager) me. 12. 52000. nó không có phương thức setTienLuong(). phương thức vẫn được gọi theo đúng đối tượng sở hữu nó.setTienThuong(15000). 12. chúng ta sẽ xem nó được gọi như thế nào.1 Sự ép kiểu và gán tham chiếu đối tượng Trong quan hệ thừa kế. Cho dùng là cùng một tên gọi. // OK you. Ngược lại. Ví dụ: Employee me = new Employee("Nguyen Anh Minh". //OK. boss1. đôi khi có sự chuyển đổi vai trò của các lớp cha và con. 10. Trong ví dụ trên. hoặc: you = (Employee)boss.setTienThuong(5000). 15). 80000. // không gán tham chiêu được me=boss1. Tính đa hình trong Java Tính đa hình là một khả năng của OOP cho phép một phương thức thực thi theo ngữ cảnh lúc chương trình đang chạy. // Gán boss cho đối tượng thứ 0 58 . // OK Tuy vậy. phương thức getLuong() được định nghĩa ở cả lớp cha và lớp con. 1987. 2000. boss. 80000. Employee you = new Employee("Nguyen Anh Tai". 1987.

Ngược lại. Mặt khác. Đặc trưng thể hiện tính đa hình trong Java. ví dụ f(int) và f(String). giả sử kiểu hiện tại của x là D. Tuy nhiên chúng ta không bao giờ phải khai báo: class Employee extends Object Mọi lớp đều là hậu duệ của Object. 3.f(“Chao ban”) thì hàm f(String) được gọi chứ không phải f(int). Bây giờ.0 Ở đây chúng ta thấy đối tượng thứ 1 và 2 in ra các giá trị vốn có của nó theo phương thức getLuong() của Employee. Ví dụ câu lệnh là x. Để kết thúc phần này ta sẽ xem xét cơ chế của việc gọi phương thức của một đối tượng trong Java được thực hiện như thế nào: 1. Lớp Object Lớp Object là lớp cha của mọi lớp trong Java. 10. 59 . nó sẽ đưa ra thông báo lỗi.f(param). // Dùng vòng lặp để in ra tên và lương từng người for (Employee e : staff) System. phương thức được gọi tùy theo kiểu hiện tại của đối tượng. Nếu trong danh sách phương thức có tên f chỉ có 1 phương thức có kiểu tham số phù hợp thì phương thức này được gọi. Cơ chế này gọi là nạp chồng (overloading).setTienThuong(2000). một lớp dẫn xuất từ C (Ban đầu x là một đối tượng lớp C nhưng sau đó được gán tham chiếu tới một đối tượng của D). Nếu D có định nghĩa một phương thức f(String) thì phương thức này sẽ được gọi. 35000). trình biên dịch đã biết rõ phương thức nào được gọi (tên và danh sách tham số). static và final hoặc là một constructor. 40000.0 Pham Quyet Tan 40000. Điều này gọi là ràng buộc tĩnh (static binding). staff[2] = new Employee("Pham Quyet Tan". 2. trình biên dịch sẽ biết chính xác phương thức cần phải gọi đó là phương thức f của lớp C. Trong lớp C có thể có nhiều phương thức có cùng tên f nhưng khác nhau ở tham số. Tiếp theo.0 Nguyen Hai Nam 50000. Cơ chế này gọi là ràng buộc động.getLuong()). 15).staff[0] = boss. Nếu trình biên dịch không thể tìm thấy phương thức có tham số phù hợp hoặc có nhiều hơn 1 phương thức phù hợp. Trình biên dịch sẽ liệt kê tất cả các phương thức tên f trong lớp C và phương thức tên f có mức độ truy cập public trong các lớp cha của C. Kết quả in ra là: Phan Thanh Ha 85000. nó sẽ tìm lên các lớp cha của D (trong đó có lớp C). 1989. // Khởi tạo cho 2 đối tượng còn lại staff[1] = new Employee("Nguyen Hai Nam". 50000. giả sử là x. Tuy nhiên đối tượng thứ 0 đã gọi phương thức getLuong() của Manager. Nếu phương thức là private. VIII. Nếu lớp D không có. do đó. đối tượng thuộc lớp Object có thể được tham chiếu tới bất kỳ đối tượng nào khác. Trình biên dịch kiểm tra kiểu của đối tượng và tên của phương thức.println(e. 1). Object obj = new Employee("AAA".getHoVaTen() + " " + e. thì không được phép khi biên dịch. 1990. trình biên dịch sẽ xác định kiểu của tham số của phương thức được gọi. Employee[] staff = new Employee[10]. nếu viết: staff[0].out. 3. Ta gọi việc getLuong() của Manager được gọi trong tình huống này là sự ràng buộc muộn hay ràng buộc động (Dynamic Binding). Trong đó x được khai báo là đối tượng của lớp C.

Từ phiên bản Java 5. Cấu trúc của một giao diện rất đơn giản: public interface <tên giao diện> { //Danh sách các phương thức } Tại lớp có cài đặt giao diện: public class <tên lớp> implements <tên giao diện> { //Phân thân lớp có chứa định nghĩa phương thức của giao diện } Ví dụ: Trong lớp Arrays của Java có phương thức sort dùng để sắp xếp các đối tượng trong một mảng. Tuy nhiên. Các lớp có sử dụng tới các phương thức này phải khai báo cài đặt giao diện bằng từ khóa implement. đó là các interface hay còn gọi là các giao diện. // OK obj = new int[10].compareTo(y) =0 nếu x = y x. } Ví dụ các lớp muốn cài đặt giao diện Comparable<Employee> phải cài đặt phương thức int compareTo(Employee objKhac). các giao diện có thể được xác định cho một kiểu tổng quát: public interface Comparable<T> { int compareTo(T objKhac). Tất cả các phương thức khai báo trong interface mặc định là public nên ta không cần khai báo public cho nó. } Phương thức compareTo nhận một đối tượng khác làm tham số và là đối tượng đem ra so sánh. // OK IX. Bây giờ chúng ta định nghĩa: x. Điều này dẫn đến việc thiết kế một giao diện: public interface Comparable { int compareTo(Object objKhac). Giao diện không phải là một class nhưng nó chỉ ra các phương thức sẽ được định nghĩa trong các lớp cài đặt nó.compareTo(y) >0 nếu x > y 60 .0 (1. Tuy nhiên. tất cả các lớp muốn sử dụng phương thức sort của Array đều phải cài đặt phương thức này trong định nghĩa của nó.obj = staff. Java hỗ trợ một kỹ thuật thay thế và rất linh hoạt.5). kết quả so sánh biểu hiện qua một số nguyên. Giao diện IX. Mở rộng hơn.compareTo(y) <0 nếu x < y x. muốn sắp xếp được thì trong định nghĩa lớp của các đối tượng này phải có cài đặt một phương thức so sánh compareTo(Object objKhac).1 Cấu trúc của giao diện Trong Java không hỗ trợ tính đa thừa kế.

Trong interface ta đang xem xét thì nó chỉ có một phương thức... Tuy nhiên nếu ta cũng khai báo chồng một phương thức compareTo() thì không được do vi phạm quy tắc chuyển kiểu: class Manager extends Employee { public int compareTo(Employee objKhac) { Manager otherManager = (Manager) objKhac.. Việc so sánh vì thế diễn ra thoải mái giữa các đối tượng Employee và Manager với nhau. nhất định ta phải có khai báo public. Tuy nhiên trong interface ta không thể khai báo các biến thành phần và không thể cài đặt nội dung của các phương thức. Đối với phiên bản Java 5. } Đối với lớp Manager thì sao. ta cài đặt compareTo như sau: public int compareTo(Object objKhac) { Employee other = (Employee) objKhac.0.. return 0. Khai báo cài đặt Comparable cho Employee: class Employee implements Comparable Giả sử các Employee được so sánh thông qua tiêu chí Luong.Luong) return 1. Các interface có thể xem như các lớp trừu tượng không có thuộc tính thành phần tuy rằng chúng có nhiều điểm khác biệt. return 0. if (Luong > other. các hằng số. if (Luong > objKhac.. } May mắn là ta không cần làm điều này vì tính kế thừa đã đảm bảo Manager cài đặt Comparable<Employee> chứ không phải Comparable<Manager>. Khi đưa một đối tượng Manager vào làm tham số so sánh. // không được . // Chuyển kiểu if (Luong < other. 61 . } . Rõ ràng là một đối tượng Manager vẫn có thể được so sánh với một đối tượng Employee về tiền lương.Luong) return -1..Luong) return 1. } .Luong) return -1. Trong phần sau đây chúng ta sẽ cài đặt một phương thức compareTo cho việc so sánh các đối tượng Employee. Các interface thường có nhiều phương thức. } Chú ý rằng các phương thức trong interface không khai báo public nhưng khi cài đặt chúng. ta có thể cài đặt: class Employee implements Comparable<Employee> { public int compareTo(Employee objKhac) { if (Luong < objKhac. nó tự động được ép sang kiểu Employee.

// OK Biến interface phải tham chiếu tới một đối tượng của một lớp có cài đặt interface đó.*.Date(. // OK  Có thể dùng toán tử instanceof để kiểm tra xem một đối tượng có được cài đặt interface hay không: if (anObject instanceof Comparable) { .Date(). int compareTo(Employee other). .Date..*.*. khai báo “double greater =1” được tự động hiểu là: public static final double greater =1. // Lỗi  Có thể khai báo một biến interface Comparable x. x = new Employee(. X. import java.sql.util.Date deadline = new java.Date today = new java. java.util.util.lang.sql. Các lớp có cài đặt interface cũng tự động được thừa kế các hằng số này. import java.2 Các tính chất của giao diện Khi sử dụng interface ta cần chú ý mấy điểm sau:  Giao diện không phải là class nên không dùng từ khóa new để tạo một đối tượng kiểu giao diện: x = new Comparable(.System. Vị trí của dấu “*” có thể là tên một class cụ thể. Trong một số trường hợp. . } Trong interface. . Thì trình biên dịch báo lỗi vì không biết Date của gói nào.sql. ta khai báo nhập thư viện: import java. Ví dụ: import java.). .).*. sử dụng dấu “*” có thể gây ra lỗi. 62 . Dấu “*” đại diện cho tất cả class.util.1 Sử dụng các package trong thư viện Java Để sử dụng các class nằm trong một gói thư viện của Java mà không cần viết đường dẫn đầy đủ của gói.IX.sql. .  Một lớp chỉ có thể kế thừa từ một lớp khác trong khi có thể cài đặt nhiều giao diện. Khi này ta phải khai báo rõ ràng cho Date ở gói nào: import java. Package X. Nếu muốn sử dụng cả hai Date trong chương trình ta phải khai báo trực tiếp: java.*. Ta cũng có thể có một khai báo nhập thư viện với từ khóa static: import static java.util.). Trong cả hai gói này đều có lớp Date nên trong dòng lệnh: Date myDate = new Date(). }  Các interface cũng có thể được kế thừa  Có thể khai báo các hằng số trong interface public interface Comparable<Employee> { double greater = 1. ..

Xóa Sinh viên.class sẽ nằm trong thư mục: com\horstmann\corejava tính từ thư mục hiện thời. tứ giác. Sắp xếp danh sách. Phương thức toString() in ra màn hình giá trị tất cả các thuộc tính của một đối tượng. hóa đơn. Các đối tượng sinh viên được so sánh theo tiêu chí điểm tổng kết. Điểm tổng kết và các phương thức phù hợp (sinh viên tự xác định xem cần những phương thức gì). Xem danh sách. thống kê học tập. Xây dựng một lớp PhuongTrinhBac1 để giải phương trình bậc 1. hình thoi. đa giác. b.2 Đặt lớp vào package Để đặt một lớp vào một package. 63 .. Khóa học. 2) + pow(y. public class Employee { . đoạn thẳng. Xây dựng các class trong java để cài đặt các lớp đối tượng: Khách hàng. Trong hệ thống đồ họa: a. hình chữ nhật. Giới tính. 2)). Hãy xây dựng các class điểm. } Nếu không có khai báo đó. Thực hành cài đặt các ví dụ trong đề tài trên. danh sách lớp và các phương thức như: Thêm sinh viên. 2. Tuổi.java Bài tập 1. ta phải có đường dẫn đầy đủ: Javac com\horstmann\corejava\Employee. c. Ta thường dùng phương pháp này với các hàm của class Math: sqrt(pow(x. khi biên dịch hoặc chạy chương trình từ cửa sổ dòng lệnh CommandLine. Do đó.horstmann.. Hãy cài đặt một phương thức toString() cho các lớp trên theo kỹ thuật ràng buộc động. tam giác. 6. 4. giỏ hàng trong một hệ thống quản lý bán hàng ở siêu thị. hình vuông. Trong đó các thành viên của lớp là các đối tượng Sinh viên có các thuộc tính như Họ và tên. 5. PhuongTrinhBac2 có cài đặt giao diện này.print(“Khong co ten lop System”). 5. Xây dựng một lớp đối tượng phương trình bậc 2 sao cho ta có thể khởi tạo một phương trình bậc 2 và biết ngay các tình trạng của nó như có nghiệm hay không và giá trị nghiệm.Khi đó các phương thức và thuộc tính tĩnh của lớp System được truy cập mà không cần có tên lớp: out. Xây dựng một lớp đối tượng để cài đặt cho lớp đối tượng lớp học bao gồm các thuộc tính như: Sĩ số. thống kê giới tính. 3. X. ta phải có khai báo package ở dòng đầu tiên của chương trình: package com. Các lớp trong gói sẽ tự động thuộc vào một đường dẫn đầy đủ theo tên của package. Xây dựng một giao diện GiaiPhuongTrinh dùng cho việc giải các phương trình bậc 1 và bậc 2 sau đó xây dựng lại các lớp PhuongTrinhBac1. Tên lớp. Trong ví dụ trên Employee. sản phẩm. Hãy cho biết một thứ tự phân cấp kế thừa của các lớp này. lớp tự động thuộc vào một package mặc định không có tên.corejava.

ta cần một định nghĩa về “động vật bốn chân” Động vật bốn chân là động vật có bốn chân để di chuyển. động vật bò sát.v…và có rất nhiều khái niệm dùng đến khái niệm này như động vật ăn cỏ.…. Đến đây ta lại bắt gặp một khái niệm trừu tượng hơn là “động vật” v. public People(int ns. Lớp SinhVien kế thừa từ People được cài đặt như sau: 64 . Ví dụ: abstract class People { private int NamSinh. một khái niệm chung cần được làm rõ là “động vật bốn chân”. Các đối tượng này đều có một phương thức toString để trả về một chuỗi bao gồm toàn bộ thông tin về chúng. Giả sử trong chương trình có các đối tượng SinhVien. Chúng thường làm cơ sở để giúp ta có được các định nghĩa cụ thể hơn: Ví dụ: Các con trâu là động vật bốn chân được nuôi phục vụ cày bừa. } abstract String toString(). Trong các định nghĩa trên. String ht) { NamSinh= ns. Cài đặt lớp và phương thức trừu tượng trong Java Khai báo: Lớp trừu tượng được khai báo như lớp thông thường nhưng có thêm từ khóa abstract.Đề tài 4. Khái niệm lớp trừu tượng Những khái niệm trừu tượng trong thế giới thực được cài đặt trong chương trình như là các lớp trừu tượng. Chúng thực sự không có một biểu hiện nào (hoặc nếu ta bắt buộc chúng có biểu hiện thì biểu hiện đó cũng không có ý nghĩa trong phạm vi đang xét. GiaoVien. } public String getHoTen() { return HoTen. Đây là tình huống sử dụng phương thức trừu tượng một cách hiệu quả. không giống như interface. Trong lập trình cũng vậy. Các con hổ là động vật bốn chân sống trong các khu rừng. HoTen = ht. Để cho các định nghĩa này thêm sáng tỏ. động vật ăn thịt. abstract String toString(). những lớp đối tượng sinh ra chỉ để cho các lớp khác kế thừa gọi là các lớp trừu tượng. private String HoTen.) II. } Ta thấy rằng một lớp trừu tượng thực sự là một lớp với đầy đủ các thành phần. Các con mèo là động vật bốn chân hay bắt chuột. ……. Chú ý là các phương thức trừu tượng không có phần thân. Lớp và phương thức trừu tượng I.

} } Khi một phương thức được khai báo là abstract thì lớp chứa nó cũng phải là một lớp abstract. Trong hệ thống quản lý bệnh nhân ở bệnh viện có 2 loại bệnh nhân là nội trú và ngoại trú trong đó bệnh nhân nội trú có tính tiền giường nằm. Hãy xây dựng một giao diện trong đó có phương thức so sánh phương tiện theo tiêu chí giá sửa. Toyota.public class SinhVien extends People { private String Lop. (Gợi ý: Phương thức TinhTien ơ lớp BenhNhan khai báo trừu tượng sau đó được khai báo chồng tại các lớp thừa kế). Mishubishi. nhà máy còn nhận bảo dưỡng cho các loại xe mô tô tay ga và xe số. 12 chỗ và 24 chỗ. Hãy xây dựng một lớp PHUONG_TIEN trừu tượng có phương thức trừu tượng là Xac_Dinh_Gia() trong đó việc tính giá sửa cho một phương tiện bằng giá của nhà máy trừ đi tiền khuyến mại.String ht. 7 chỗ.valueOf(NamSinh) + String.valueOf(DiemTongKet) + HoTen. Ngoài ra. Một nhà máy sử chữa phương tiện vận chuyển có các loại xe ô tô thuộc nhiều hàng khác nhau như Honda. 4 chỗ. Mercedec. Xây dựng chương trình nhập vào dữ liệu cho 5 chiếc xe cả ô tô và mô tô và in ra màn hình theo thứ tự tăng dần của giá sửa. Bài tập 1. private double DiemTongKet. c. Xây dựng một lớp BenhNhan trừu tượng có các thuộc tính như họ và tên. Ford. Khi kế thừa một lớp có chứa phương thức trừu tượng thì phương thức đó bắt buộc phải được cài đặt. DiemTongKet=dtk. // Phương thức khởi tạo public SinhVien(int ns. b. có phương thức tính tiền phải thanh toán bằng tiền điều trị cộng với tiền giường nằm. 3.ht). } // Cài đặt phương thức toString public String toString() { return String. 65 . Khi sử dụng phương thức abstract cho một lớp thì nhất thiết phải có một lớp khác kế thừa và khai báo cài đặt chồng thì mới có tác dụng. Kia.double dtk) { //Dùng phương thức khởi tạo của lớp cha super(ns. Sau đó xây dựng hai lớp BenhNhanNoiTru và BenhNhanNgoaiTru kế thừa lớp BenhNhan. Lop = l. Mỗi hãng ô tô lại có nhiều kiểu khác nhau như 2 chỗ.String l. tiền điều trị. a. Nhà máy có các chế độ khuyến mại và bảo hành khác nhau tùy theo xe của từng hãng.

i++) 3. Sau đó dùng phương thức addElement() để thêm đối tượng này vào vị trí cuối của Vector. I.get(i)). Kích thước của Vector được tăng theo một lượng đặt trước hoặc được tự động tăng gấp đôi khi ta cần tăng dung lượng của nó. 2. System.println(v.out.capacity()).println(v. tham số thứ 2 chỉ số phần tử được thêm vào mỗi khi dung lương của Vector bị hết.  Nếu là 2 tham số thì tham số thứ nhất chỉ số phần tử ban đầu.lang như Integer. java. System.util.i<10. Dòng 2-7: Vòng lặp để nhập và lưu kết quả nhập vào Vector.i++) 10.util.out. System.nextInt()).Integer p = new java.out.print("So nguyen thu " + String. Lưu trữ và xử lý đối tượng Trong phần này chúng ta sẽ đề cập tới các lớp tiện ích của Java trong gói java. for (int i=0. for (int i=0. 6.lang.Vector(5.valueOf(i) + ":"). 12. { 4. lưu vào một Vector rồi in ra để kiểm tra: // Nhâp 10 doi tuong so nguyen 1. 15. Lớp Vector có 3 constructor:  Nếu dùng constructor không tham số thì Java tự động cấp cho ta số phần tử ban đầu là 10 và nhân đôi mỗi khi có nhu cầu mở rộng.valueOf(i) + " la:"). Dòng 1: Khai báo một đối tượng v thuộc lớp Vector. // In ra de kiem tra 9. Để lưu các giá trị dữ liệu nguyên thủy.2).Đề tài 5. } 8.out. System.  Nếu là 1 tham số thì đâu là số phần tử ban đầu. } 14. Vì vậy thao tác chèn một phần tử mới vào một Vector sẽ nhanh hơn khi kích thước của nó còn đủ dùng. 7. Ở đây ta phải khai báo một biến đối tượng kiểu Integer chứ không phải là một kiểu nguyên thủy int.out. Chúng ta sẽ xem xét việc sử dụng interface Enumeration để cho phép duyệt lặp trên các cấu trúc như Vector.println(v. Vector lưu trữ tham chiếu của các đối tượng nên chương trình có thể dùng Vector để lưu tham chiếu đến bất kỳ đối tượng nào. 66 . Ở đây ta đã dùng một constructor với 2 tham số là số phần tử ban đầu và số sẽ tăng khi Vector có nhu cầu tăng (mặc định sẽ gấp đôi số hiện có). 13.print("Nhap so nguyen thu " + String.i<10. 5. ta phải sử dụng các lớp trong java. { 11.Integer(nhap. java. v.1 Lớp Vector Lập trình viên dùng lớp Vector để lưu trữ các đối tượng có kiểu giống nhau nhưng có thể thay đổi động về kích thước tùy theo nhu cầu.Vector v = new java. Sau đây là một ví dụ nhập vào 10 số nguyên.util dùng cho việc lưu trữ và xử lý các đối tượng. Lớp Vector và giao diện Enumeration I. Long hay Float thay vì dùng chính kiểu đó.lang. khi cần cũng tự động nhân đôi. System.addElement(p).size()).

Dòng 15: Kích số lượng các phần tử tối đa hiện có của Vector (=11). Các lớp thường khai báo chồng phương thức equals() để dùng trong việc so sánh các đối tượng của mình. } // Ke thua lop People public class SinhVien extends People { 67 . //Ho Va Ten //constructor public People(int ns. Thực ra thì phương thức get(chỉ số) cho ta một tham chiếu đến đối tượng có chỉ số tương ứng được lưu trong Vector nhưng ở đây đối tượng số nguyên đã tự động in ra giá trị. Đối tượng key và các phần tử của Vector đươck so sánh với nhau bởi phương thức equals(). contains(key): để kiểm tra xem trong vector có phần tử so khớp với key hay không. removeAllElements(): Xóa tất cả các phần tử. firstElement(): Trả về tham chiếu tới phần tử đầu tiên.2 Giao diện Enumeration Sử dụng phương thức elements() của một đối tượng Vector sẽ trả về một đối tượng Enumeration cho phép chương trình duyệt lặp trên danh sách phần tử của Vector. Một số phương thức của Vector: removeElementAt: Xóa một phần tử ở một vị trí xác định.//Nam Sinh protected String HoVaTen. Sử dụng removeElement(Object) để xóa một phần tử xuất hiện đầu tiên trong Vector có giá trị bằng với Object. public abstract String toString(). Dòng 14: Phương thức trả về kích thước thực tế của Vector. } // Phuong thuc tinh tuoi protected abstract int TinhTuoi(). lastElement(): Trả về tham chiếu tới phần tử cuối cùng trong Vector. Đối tượng Enumeration có các phương thức quan trọng sau: hasMoreElement(): Trả về true nếu vẫn còn phần tử trong Vector.Ngoài ra ta cũng có thể sử dụng insertElementAt() để chèn phần tử vào một vị trí xác định hoặc sử dụng setElementAt() để đặt giá trị cho một phần tử tại một vị trí. trimToSize(): Giảm số lượng phần tử của Vector. tức là số phần tử thực sự Vector lưu trữ (=10) . I. Đoạn chương trình sau duyệt và in ra danh sách các sinh viên: abstract class People { protected int NamSinh. Dòng 12: Dùng phương thức get(chỉ số) để in ra giá trị của phần tử có chỉ số tương ứng.String ht) { NamSinh=ns. indexOf(Object): Trả về chỉ số của đối tượng đầu tiên so khớp với Object. HoVaTen=ht. isEmpty(): Xác định liệu Vector là trống. nextElement(): Trả về tham chiếu tới phần tử tiếp theo trong Vector.

valueOf(ID)+ "\n" +"Tuoi:"+ String.addElement(k3).addElement(k2)."Letio3". sinh vien dau tien co ma so 1 SinhVien.addElement(k5). return (homnay. } // Ham main public static void main(String[] argv) { // Dat gia tr? bien static.valueOf(DiemTongKet)+"\n" +"Ho va ten:"+ HoVaTen. sv. sv."Letio3". // bien doi tuong Vector java.getYear() ."Nguyen Thi Mai 1". sv."Letio3".Date homnay = new java. SinhVien k4= new SinhVien(83.// ma so chung de cap phat cho moi sinh vien // constructor public SinhVien(int ns. } // Phuong thuc tinh tuoi protected int TinhTuoi() { java.Vector(5)."Pham Thi Mai 3".util.6).String ht."Phan Thi Mai 4"."Letio3". sv. SinhVien k5= new SinhVien(84. // Them sinh vien vao Vector SinhVien k2 = new SinhVien(81. SinhVien k3 = new SinhVien(82. SinhVien k1 = new SinhVien(80.Vector sv = new java.TinhTuoi()) + "\n" +"Diem Tong Ket:"+ String.double dtk) { super(ns.addElement(k4). // Tang ma so len 1 den gan cho SinhVien sau MaSo+=1.util.9).MaSo=1.String l.util.//goi constructor cua lop cha la People Lop = l.//Hang so private int ID. } // Khai bao chong phuong thuc toString() public String toString() { return "Ma so:" + String. // Diem tong ket public final String mauda ="vang".5)."Tran Thi Mai 2".valueOf(this.// Ma so SinhVien protected static int MaSo.8).Date(). DiemTongKet=dtk. 68 . // Id cua SinhVien duoc gan bang gia tri MaSo hien thoi cua lop ID=MaSo.NamSinh +1)."Hoang Thi Mai 5".ht).addElement(k1).7).util."Letio3". sv.private String Lop.// Ten lop private double DiemTongKet.

hasMoreElements()) { // Ep kieu. Mảng trong Java và lớp ArrayList II.println(g.*. System. Trong phần này ta sẽ đi sâu khai thác các đặc tính của mảng và một số thuật toán thông dụng thông qua các ví dụ."Pham Anh Hoa"). while (enu.elements(). kieu Object la kieu cha cua moi kieu nen luon ep duoc SinhVien g = (SinhVien)enu. } //People p = new People(20.// Dung interface Enumeration de duyet cac phan tu cua Vector java.util.nextElement(). Ví dụ: Đếm tần suất của các phần tử của một mảng: import javax.toString()).swing. bao loi vi People là lớp trừu tượng } } Kết quả thực hiện như sau: II.out.1 Mảng trong Java Trong phần “Ngôn ngữ Java căn bản” ta đã xem xét một biến mảng được khai báo và sử dụng như thế nào.Enumeration enu = sv. public class StudentPoll { // Hàm main public static void main( String args[] ) 69 .

print(out). int first. 8. 7. 2. element < array2.tức là sau mỗi vòng lặp duyệt. các câu trả lời nằm trong khoảng từ 1 đến 10 nên khai báo một mảng 11 phần tử để có thể sử dụng chính giá trị 10 làm chỉ số của mảng. 8. element++ ) { // So sánh 2 phần tử liền kề và đổi chỗ nếu cần if ( array2[ element ] > array2[ element + 1 ] ) swap( array2. 6. 6. 6.2. Chỉ cần duyệt mảng TraLoi 1 lần ta đã có ngay kết quả. 5. array3[ first ] = array3[ second ]. 6. 8. answer < TraLoi. 8. // Đưa kết quả vào một chuỗi for ( int rating = 1. 8. 6. 7. 2. 7. Các thuật toán cơ bản trên mảng Ví dụ: Sắp xếp tuyến tính Đây là một ví dụ sắp xếp các phần tử của mảng tăng dần theo thuật toán “nổi bọt” . rating < TanSuat. array3[ second ] = hold. answer++ ) ++frequency[ TraLoi[ answer ] ]. // Sắp xếp các phần tử của mảng public void bubbleSort( int array2[] ) { // Duyệt qua mỗi phần tử của mảng for ( int pass = 1. 10. 10 }.length. lưu giá trị vào mảng TanSuat tại vị trí tương ứng.out. for ( int answer = 0. // Với mỗi phần tử của mang TraLoi. II. 6. // In ra System. 6.length . 6. }} Trong ví dụ này. 10. 5. 7. 3. 7. int second ) { int hold. pass++ ) { // Vòng lặp so sánh và đổi chỗ for ( int element = 0. element. 1.length. 9. 3. 8. rating++ ) output += rating + "\t" + TanSuat[ rating ] + "\n". 4. // Mảng đếm tần suất int TanSuat[] = new int[ 11 ]. 6. sử dụng giá trị đó như là chỉ số của mảng TanSuat sau đó đếm sự xuất hiện của nó trong TraLoi.length. 6. 5. 8. phần tử nào lớn nhất sẽ bị đẩy xuống cuối cùng. // Biến trung gian để hoán đổi hold = array3[ first ]. 5. 6. element + 1 ).pass.{ // Khai báo một mảng các câu trả lời int TraLoi[] = { 1. 5. } 70 . pass < array2. 4. }} } // Hàm đổi chỗ 2 phần tử của một mảng public void swap( int array3[].

Giả sử ta có một mảng: int[] b={1.34. } return -1.100}.5.3 Class Arrays Java hỗ trợ một lớp mảng trong thư viện java. // Nếu khóa cần tìm trùng với phần tử giữa thì trả về kết quả ngay if ( key == array[ middle ] ) return middle. // chỉ số của phần tử trung gian // Lặp cho đến khi chỉ số dưới lớn hơn hoặc bằng chỉ số trên while ( low <= high ) { // Xác định chỉ số phần tử giữa middle = ( low + high ) / 2. Đối với các mảng đã được sắp xếp.1. so sánh 7 với 5 thì 7>5 nên phần tử cần tìm nếu có sẽ nằm ở phần sau của nửa này gồm 2 phần tử 7. 71 .67.7.Ví dụ: Tìm kiếm nhị phân trên mảng đã được sắp xếp: Thông thường việc tìm kiếm diễn ra bằng phép duyệt lần lượt các phần tử của mảng. Ta gọi phương pháp này là tìm kiếm tuyến tính. Lần phân đôi cuối cùng này cho ta kết quả.8. Giả sử ta cần tìm vị trí của một phần tử có giá trị 7. int key ) { int low = 0.util. ta có một phương pháp tìm kiếm hiệu quả hơn.8. Tiếp tục làm việc này với nửa trước của mảng.  sort: để sắp xếp mảng  binarySearch: Tìm kiếm nhị phân trên mảng đã được sắp.Arrays để lập trình viên thao tác trên mảng. ta so sánh 7 với vị trí đứng giữa của mảng là 34 thì 7 < 34 nên ta chắc chắn nếu có thì 7 sẽ nằm ở nửa trước của mảng. Thay vì phải lập trình. // Chỉ số dưới int high = array.length . // Không tìm thấy } II. đặt lại chỉ số trên else if ( key < array[ middle ] ) high = middle . Đã được sắp xếp tăng dần.1.89. // Khóa lớn hơn phần tử giữa. đặt lại chỉ số dưới else low = middle + 1. // Nếu khóa nhở hơn phần tử giữa. gọi là tìm kiếm nhị phân.56. Arrays hỗ trợ các phương thức:  fill: để nạp giá trị cho mảng. Trước tiên. Chủ yếu các phương thức của lớp này là static. // Chỉ số trên int middle. Thủ tục này được cài đặt như sau: public int binarySearch( int array2[].

count++ ) System. } // Tìm một giá trị trong mảng intValues public int searchForInt( int value ) 72 .print( intValues[ count ] + " " ).out. count < intValues.length.length.println(). 6 }.out. count < intValuesCopy.out. 3. 2. 5.out. equals: So sánh mảng Sau đây là ví dụ về sử dụng lớp Arrays: import java.out.4 }. public class UsingArrays { private int intValues[] = { 1. private int filledInt[]. System.arraycopy( intValues. // Sao chép mảng } // In giá trị của các mảng public void printArrays() { System.print( "\nfilledInt: " ). 7.sort( doubleValues ).out. 3. private double doubleValues[] = { 8. intValues. 9. count++ ) System. count < doubleValues.out.print( "doubleValues: " ). 7 ).print( filledInt[ count ] + " " ).length.4.out. System. // Nạp giá trị cho mảng filledInt với giá trị 7 Arrays.print( intValuesCopy[ count ] + " " ). 0. count++ ) System. // Sắp xếp mảng doubleValues System.length ].util. 0. intValuesCopy. for ( int count = 0.length. System. System. Arrays.print( doubleValues[ count ] + " " ).fill( filledInt. intValuesCopy[].print( "\nintValues: " ). 0.9. for ( int count = 0. 4.*. // Khởi tạo các mảng public UsingArrays() { filledInt = new int[ 10 ].length ). count++ ) System.out.print( "\nintValuesCopy: " ). intValuesCopy = new int[ intValues.3. for ( int count = 0. for ( int count = 0. count < filledInt.2.

Sau đây là chương trình ví dụ sử dụng ArrayList.*. filledInt ). } // So sánh nội dung mảng public void printEquality() { boolean b = Arrays.equals( intValues. Các lớp tập hợp cài đặt Lists là ArrayList. b = Arrays.out.binarySearch( intValues.out. import java. // Tạo một ArrayList. intValuesCopy ). Về cơ bản thì ArrayList giống với Vector chúng ta đã xem xét ở trên. usingArrays.println( "intValues " + ( b ? "==" : "!=" ) + " filledInt" ). value ). Lists là một giao diện kế thừa giao diện Collections nên nó cho phép lập trình viên truy cập các phần tử qua chỉ số.add( Color. System.println( "intValues " + ( b ? "==" : "!=" ) + " intValuesCopy" ). System.magenta ). import java. // Thêm đối tượng cho nó list. Ở đây ta đặt các đối tượng String và Color vào cùng một ArrayList sau đó xóa đi các phần tử String sử dụng một đối tượng Iterator.printArrays(). System. thêm các phần tử cho nó public CollectionTest() { ArrayList list = new ArrayList(). "blue" }. } // Hàm main public static void main( String args[] ) { UsingArrays usingArrays = new UsingArrays().searchForInt( 5 ). }} III Danh sách trong java và giao diện Lists Lists là một chuỗi có thứ tự các phần tử cho phép các phần tử có thể giống nhau.printEquality(). System. location = usingArrays.println( ( location >= 0 ? "Tìm thấy 5 tại vị trí " + location : "Không thấy" ) + " trong mảng intValues" ).out.awt.println( ( location >= 0 ? "Tìm thấy 8763 tại " + location : "Không thấy 8763" ) + " trong mảng intValues" ).util.equals( intValues.{ return Arrays.searchForInt( 8763 ).Color. ArrayList là một lớp tập hợp có thể thay đổi kích thước. usingArrays. int location = usingArrays. LinkedList và Vector. "white". public class CollectionTest { private String colors[] = { "red".out. // Thêm một đối tượng Color // Thêm các đối tượng String 73 .

out.Nhập vào từ bàn phím 1 số khác và tìm xem số đó có trong số n số vừa nhập không. // output list contents System. Sau đó: .iterator().hasNext() ) if ( iterator. count++ ) System.size(). count++ ) System.Thêm sinh viên. for ( int count = 0.cyan ).println( "\n\nArrayList sau khi gọi removeStrings: " ).add( colors[ count ] ).out. for ( int count = 0. n nhập từ bàn phím. count++ ) list. 74 . . // Xóa phần tử } // Hàm main public static void main( String args[] ) { new CollectionTest(). } public void removeStrings( Collection collection ) { // Khai báo đối tượng iterator iterator iterator = collection.out.length. list.Tính tổng của n số này. . // Lặp trong khi tập hợp vẫn còn phần tử while ( iterator.remove(). Viết chương trình quản lý danh sách một lớp học với các chức năng .Tìm kiếm sinh viên .print( list. count < colors.for ( int count = 0.print( list.get( count ) + " " ). count < list. count < list.size().Sắp xếp danh sách theo tên 2.Sắp xếp n số theo thứ tự tăng dần .Xóa sinh viên .out. // Thêm một đối tượng Color // In ra nội dung System. } } Bài tập 1. Viết chương trình nhập vào n số nguyên và số thực.println( "\nArrayList: " ).add( Color. // Xóa tất cảcác đối tượng String removeStrings( list ).next() instanceof String ) iterator.get( count ) + " " ).

Thư viện này cho phép ta làm việc với các luồng nhập xuất qua việc cung cấp các lớp: FileInputStrem. ta khai báo khối thư viện: import java.io.. FileWriter và rất nhiều lớp khác.  Lớp System. đọc từ tập tin.Đề tài 6. Khái niệm luồng vào ra (I/O stream) Luồng là dòng chảy của dữ liệu. Sự phân cấp các class trong gói java.lang. Khi cần làm việc với luồng.err: Đây là dòng lỗi chuẩn cho phép một chương trình đưa ra các thông báo lỗi trên màn hình. Ví dụ System. FileOutputStream. FileReader. tệp tin.out: Dòng xuất chuẩn dùng để hiển thị kết quả trên màn hình.  Lớp System. I...  Luồng xuất (output stream): là tất cả những gì được gửi từ máy tính ra ngoài thông qua các thiết bị ngoại vi. như đọc từ bàn phím.err có thể đưa thông báo lỗi ra một file. Có 2 loại luồng:  Luồng nhập (input stream): là tất cả gì từ thế giới bên ngoài được đưa vào máy tính.. máy in. như màn hình. Các luồng vào ra dữ liệu với file Một khả năng quan trọng mà các ngôn ngữ lập trình phải có là việc quản lý các luồng dữ liệu vào ra hệ thống máy tính giúp các chương trình có thể giao tiếp dữ liệu với thế giới bên ngoài.in: Dòng nhập chuẩn thường đến từ bàn phím và được dùng để đọc các ký tự dữ liệu. .io thể hiện qua bảng sau: java.Object File FileDescriptor InputStream ByteArrayInputStream FileInputStream FilterInputStream BufferedInputStream DataInputStream PushbackInputStream ObjectInputStream PipedInputStream SequenceInputStream OutputStream ByteArrayOutputStream FileOutputStream FilterOutputStream BufferedOutputStream DataOutputStream PrintStream ObjectOutputStream 75 .*. Đối với mội luồng lại có các dòng bao gồm:  Lớp System. Các dòng này có thể bị đổi hướng đến nhiều nguồn khác nhau.

 skip(): Phương thức này bỏ qua „n‟ byte dòng vào.  available(): Phương pháp này trả về số lượng byte có thể đọc được mà không phải chờ. Nó gây ra ngoại lệ IOException nếu lỗi xảy ra. Nó gây ra ngoại lệ IOException nếu lỗi xảy ra. Nó dùng để giải phóng mọi tài nguyên dòng đã sử dụng. Nó gây ra ngoại lệ IOException nếu lỗi xảy ra. Nó trả về số byte hiện tại có trong dòng.  read(byte[]): Trả về số byte đọc được hay „-1‟ nếu như đã đọc đến cuối dòng.PipedOutputStream RandomAccessFile Reader BufferedReader LineNumberReader CharArrayReader FilterReader PushbackReader InputStreamReader FileReader PipedReader StringReader Writer BufferedWriter CharArrayWriter FilterWriter OutputStreamWriter FileWriter PipedWriter PrintWriter StringWriter Sau đây chúng ta xem xét các class quan trọng thường được sử dụng: II. Có các phương thức chính sau:  read(): Đọc các byte dữ liệu từ một dòng. Khi một phương thức phải chờ. Phương thức này sử dụng để di chuyển tới vị trí đặc biệt bên trong dòng vào. Nếu như không có byte dữ liệu nào.  read(byte[]. Nó trả về true nếu dòng hỗ trợ ngược lại trả về false. 76 .int. nó phải chờ.  mark(): Đánh dấu vị trí hiện tại của dòng. Nó gây ra ngoại lệ IOException nếu có lỗi xảy ra. Lớp InputStream: Là một lớp trừu tượng định nghĩa cách thức nhận dữ liệu. Nó gây ra ngoại lệ IOException nếu lỗi xảy ra. Nó trả về số byte thực sự đọc được cho đến khi kết thúc dòng. ‟-n‟ chỉ định số byte được bỏ qua.  reset(): Phương thức này định vị lại dòng theo vị trí được đánh lần cuối cùng. Nó không phải là phương thức tin cậy để thực hiện tiến trình xử lý đầu vào. các luồng đang thực hiện phải tạm dừng cho đến khi có dữ liệu.int): Nó cũng đọc vào một mảng byte.  close(): Phương thức này đóng dòng. Luôn luôn đóng dòng để chắc chắn rằng dòng xử lý được kết thúc.  markSupported(): Trả về giá trị boolean chỉ ra rằng dòng có hỗ trợ các khả năng mark và reset hay không.

Ví dụ:File f = new File("C:\jdk1. Lớp OutputStream Là lớp trừu tượng định nghĩa cách ghi các kết xuất đến dòng.  FileInputStream(File f): Tham số là đối tượng file để tạo luồng. Lớp này có 3 phương thức khởi tạo sau:  FileInputStream(String name): Tham số là tên của tập tin để tạo luồng.  FileOutputStream(FileDescriptor fdObj) VI.java"). Lớp này cung cấp các phương thức thiết lập các tập tin và các thư mục.  FileOutputStream(File f). int. String name). ta dùng File trong tất cả các thao tác quản lý file và thư mục. hoặc đối tượng FileDescriptor làm một đối số.  write(byte[]): Phương thức này phong toả cho đến khi một byte được ghi. một mảng các byte. Ví dụ: InputStream in = new FileInputStream(“C:\\LETI\\JAVA\\Account. được dẫn xuất từ lớp cha OutputStream. Lớp File Lớp này được sử dụng để truy cập các đối tượng tập tin và thư mục. Các tập tin đặt tên theo qui ước đặt tên tập tin của hệ điều hành. Lớp FileOutputStream Lớp này cung cấp khả năng ghi dữ liệu xuống tập tin.  File(File dir. Nó được dùng để giải phóng mọi tài nguyên gắn với dòng.  FileInputStream(FileDescriptor fdObj): Tham số là đối tượng FileDescriptor để tạo luồng. Nó kích hoạt IOException nếu lỗi xảy ra. Nó cung cấp một tập các phương thức trợ giúp tạo ra. Lớp FileInputStream Kế thừa từ InputStream. Các phương thức bao gồm:  write(int): Phương thức này ghi một byte. Có 3 cách để tạo các đối tượng từ lớp File:  File(String path).4\bin\hello. Lớp OutputStream định nghĩa ba dạng khác nhau của phương thức để có thể ghi một byte riêng lẻ.  write(byte[]. Các đối tượng của lớp này được tạo ra nhờ đường dẫn tới file. hay một đoạn của một mảng byte.III. V. ghi và xử lý kết xuất các dòng. Nó gây ra ngoại lệ IOException nếu lỗi xảy ra.  close(): Phương thức đóng dòng. Nó kích hoạt IOException nếu lỗi xảy ra. Có 3 phương thức khởi tạo:  FileOutputStream(String name). int): Phương thức này ghi mảng các byte. 77 . Như vậy. Tất cả các thao tác thư mục và tập tin được thực hiện thông qua các phương thức của lớp File.  flush(): Phương thức này xả sạch dòng. lớp này cho phép đọc vào từ một tập tin dưới dạng một stream. String name).txt”). IV. Đệm dữ liệu được ghi ra dòng. đối tượng File. Dòng phải chờ cho đến khi tác vụ ghi hoàn tất.  File(String path.

Chương trình ví dụ: public class Test { public static void main(String args[]) { File f = new File("test"). // Lấy đường dẫn tuyệt đối System.").  public void createTempFile(String pattern.  public String toURL(): trả về đối tượng URL tương ứng với tập tin.exists()).  public String getParent(): lấy tên thư mục cha.4\bin".println(f.  public boolean isFile(): cho biết tệp tin có hợp lệ hay không (true nếu có).  public boolean isDirectory(): cho biết tập tin có phải thư mục hay không (true nếu có).  public String gePath(): lấy đường dẫn của tập tin.out. Các phương thức:  public String getName(): lấy tên đối tượng tập tin. File dir): tạo tập tin tạm thời. // Kiểm tra sự tồn tại } } VII.  public boolean canRead(): cho biết tập tin được phép đọc hay không (true nếu có)  public void setReadOnly(): đặt thuộc tính chỉ đọc. Nhập xuất lọc Là một kiểu dòng có được từ việc thay đổi cách xử lý dòng hiện có.getAbsolutePath()). "hello. true nếu thành công.  renameTo(File dest): đổi tên tập tin hiện tại sang tên mới. "Hello. File f = new File(curDir.gif. 78 .  public String[ ] list(FilenameFilter filter): lấy danh sách tập tin thoả mãn điều kiện lọc. System. Nó thực hiện xử lý một quá trình nào đó trên các byte được truyền từ đầu vào đến đầu ra.  public String[ ] list(): lấy danh sách các tập tin và thư mục.  public long length(): cho biết kích thước tập tin (byte).  public boolean mkdir(): tạo một thư mục từ đối tượng file.java").  public boolean isHidden(): kiểm tra xem tập tin có ẩn hay không (true nếu có).hoặc File f = new File("C:\jdk1. true nếu xoá thành công. Các lớp.  public String getAbsolutePath(): lấy đường dẫn tuyệt đối của tập tin.java").  public boolean canWrite(): cho biết tin có cho phép ghi hay không (true nếu có).out. ví dụ *. các dòng nhập xuất lọc của java sẽ giúp ta lọc vào/ra theo một số cách.println(f.  public booean delete(): xoá tập tin.  public Boolean createNewFile(): tạo một tập tin mới. Bộ lọc nằm giữa một dòng nhập và một dòng xuất.  public void deleteOnExit(): yêu cầu xoá tập tin khi chương trình chấm dứt.  public String toString(): trả về đường dẫn của tập tin. hoặc File curDir = new File(".

*. Lớp FilterInputStream được thiết kế sao cho có khả năng kết chuỗi nhiều bộ lọc. VII.StringTokenizer.2 Lớp FilterOutputStream Lớp này là một dạng bổ trợ cho lớp FilterInputStream. VIII. VIII. Nó giúp chương trình đọc/ghi lượng dữ liệu nhỏ không ảnh hưởng lớn đến hiệu năng chung của hệ thống.Các bộ lọc có thể ghép với nhau khi đó đầu ra của bộ lọc này trở thành đầu vào của bộ lọc kia. // Diem tong ket public final String mauda ="vang". VIII. Để thực hiện điều này chúng ta dùng vài tầng lồng nhau.// Ma so SinhVien protected static int MaSo. public class SinhVien extends People { private String Lop. Một dòng có thể được đọc và đưa kết quả cho một dòng khác. VII.io.1 Lớp FilterInputStream: Đây là lớp trừu tượng.// ma so chung de cap phat cho moi sinh vien public SinhVien(int ns. một sử dụng kích cỡ vùng đệm ngầm định. mỗi sinh viên nằm trên một dòng trong file: // Ke thua lop People import java. Vào/ra có sử dụng bộ đệm Vùng đệm là kho lưu trữ dữ liệu. Chương trình sau đây đọc và ghi thông tin của đối tượng SinhVien theo một format. Chúng ta có thể lấy dữ liệu từ vùng đệm thay vì quay trở lại nguồn ban đầu của dữ liệu.//goi constructor cua lop cha la People Lop = l.ht). import java. 79 .2 Lớp BufferedOutputStream Lớp này định nghĩa hai phương thức thiết lập. Lớp này định nghĩa chồng tất cả các phương thức của OutputStream và không đưa thêm bất kì phương thức mới nào.// Ten lop private double DiemTongKet. Dữ liệu ghi vào lớp này có thể sửa đổi theo nhu cầu để thực hiện tác vụ lọc và sau đó được chuyển tới đối tượng OutputStream. Nó là cha của tất cả các lớp dòng nhập lọc.1 Lớp BufferedInputStream: Lớp này tự động tạo ra và duy trì vùng đệm để hỗ trợ thao tác vào. Nhờ đó chương trình có thể đọc dữ liệu từ dòng từng byte một mà không ảnh hưởng đến tốc độ thực hiện của hệ thống. Java sử dụng cơ chế nhập/xuất có lập vùng đệm để tạm thời lập cache dữ liệu vào/ra của một dòng.util.//Hang so private int ID. một cho phép chỉ định kích cỡ của vùng đệm xuất.double dtk) { super(ns. Nó là lớp cha của tất cả các lớp dòng xuất lọc.String ht.String l.

util.Vector(5).parseInt(t.Date homnay = new java. sv.util. "|").valueOf(this.nextToken()).parseDouble(t.MaSo=1. NamSinh = Integer. // Tang ma so len 1 den gan cho SinhVien sau MaSo+=1. // Them sinh vien vao Vector SinhVien k2 = new SinhVien(81. } // Đọc thông tin 1 sinh viên từ bộ đệm đọc public void DocData(BufferedReader in) throws IOException { String s = in.readLine().6). // bien doi tuong Vector lưu các sinh viên java. 80 . MaSo = Integer. sv. SinhVien k1 = new SinhVien(80. sinh vien dau tien co ma so 1 SinhVien.parseInt(t.Date(). } // Ghi thông tin sinh viên vào file public void GhiData(PrintWriter out) throws IOException { out.util. // Id cua SinhVien duoc gan bang gia tri MaSo hien thoi cua lop ID=MaSo.Vector sv = new java. } // Khai bao chong phuong thuc toString() public String toString() { return String.valueOf(ID)+ "|" + String."Letio3"."Tran Thi Mai 2".nextToken()).toString()). // Đọc một dòng trong bộ đệm StringTokenizer t = new StringTokenizer(s.valueOf(DiemTongKet)+"|" + HoVaTen."Nguyen Thi Mai 1". HoVaTen = t.NamSinh +1). DiemTongKet = Double.nextToken()).nextToken().util. } // Phuong thuc tinh tuoi protected int TinhTuoi() { java.getYear() ."Letio3".DiemTongKet=dtk.println(this.TinhTuoi()) + "|" + String.addElement(k2).5). } // Ham main public static void main(String[] argv) { // Dat gia trị bien static. return (homnay.addElement(k1).

"Letio3". String mode). } catch(Exception ep) {} // Doc tu file ra SinhVien[] svs = new SinhVien[5]. điều này cho phép đọc tập tin theo chế độ chỉ đọc hoặc đọc-ghi."". kieu Object la kieu cha cua moi kieu nen luon ep duoc SinhVien g = (SinhVien)enu. SinhVien k5= new SinhVien(84."Pham Thi Mai 3".dat")). } out.0). Lớp này cũng hỗ trợ các quyền cơ bản về đọc hoặc ghi tập tin. try { PrintWriter out = new PrintWriter(new FileWriter("C:\\LETI\\JAVA\\Sinhvien.i<svs. Do vây.DocData(in). }} IX.println(svs[i].length.i++) { svs[i] = new SinhVien(0.9).addElement(k3). Lớp RandomAccessFile thực hiện cả hai việc nhập và xuất.elements().util."Letio3".8). // Dung interface Enumeration de duyet cac phan tu cua Vector java."Phan Thi Mai 4". Lớp RandomAccessFile Lớp RandomAccessFile cung cấp khả năng thực hiện vào/ra theo một vị trí cụ thể bên trong một tập tin.0. try { BufferedReader in = new BufferedReader(new FileReader("C:\\LETI\\JAVA\\Sinhvien. for(int i=0. sv. 81 ."". SinhVien k4= new SinhVien(83.addElement(k5). dữ liệu có thể đọc hoặc ghi ở vị trí ngẫu nhiên thay vì liên tục.SinhVien k3 = new SinhVien(82.7).close().GhiData(out).i<svs. sv. } } catch(IOException ep) {} for(int i=0. g.Enumeration enu = sv.out. sv. có thể thực hiện I/O bằng các kiểu dữ liệu nguyên thuỷ. while (enu."Hoang Thi Mai 5". Đối tượng thuộc lớp RandomAccessFile có thể được khởi tạo theo hai cách:  RandomAccessFile(String name. svs[i].i++) System.length.nextElement().toString()).addElement(k4)."Letio3".dat")).hasMoreElements()) { // Ep kieu. Trong lớp này.

Trong một lớp cài đặt Serializable. // Chỉ số nắm giữ hàng hóa và dịch vụ của khách hàng.  length( ): Trả về chiều dài của tập tin tính theo byte. X. public class AccountRecord implements Serializable { private int account. Đối tượng System. Giao diện Serializable được biết đến như là một giao diện “đính kèm” bởi vì bản thân nó không chứa bất kỳ một phương thức nào. "r"). Nó giúp ta đọc các ký tự được người dùng gõ vào từ bàn phím.txt”. Để cho phép một đối tượng của một lớp có thể sử dụng với ObjectInputStrems và ObjectOutputStreams. Mặc định thì tất cả các kiểu dữ liệu nguyên thủy đều là tuần tự hóa. số dư tài khoản public AccountRecord()// constructor không tham số { this( 0. Ví dụ: RandomAccessFile file = new RandomAccessFile(“C:\\LETI\\JAVA\\Account. phải kiểm tra xem định nghĩa của lớp (hoặc lớp cha) có cài đặt Serializable hay không. String mode). 0.io. private double balance. RandomAccessFile(File f. Sau đây là một ví dụ về xây dựng một lớp đối tượng khách hàng cho một ứng dụng ngân hàng sau đó ghi chúng vào file: import java. lập trình viên phải đảm bảo rằng mọi biến của lớp phải có kiểu Serializable hoặc phải khai báo một biến là transient để bỏ qua trong quá trình tuần tự hóa.0 ). "".chế độ chỉ đọc. Truy cập file ở chế độ tuần tự Khi làm việc với Java.  getFilePointer( ): Trả về vị trí hiện hành của con trỏ tập tin. tất cả đều là đối tượng. private String firstName.Serializable. lớp đó phải khai báo cài đặt giao diện Serializable. "". Một class cài đặt giao diện này được gán một thông báo rằng đối tượng của lớp là một đối tượng Serializable. Các phương thức mới thêm vào bao gồm:  seek( ): Thiết lập con trỏ tập tin tới vị trí cụ thể bên trong tập tin. mode = "rw" . ta có thể sử dụng phương thức read() hoặc kết nối với một luồng trung gian khác. Với các kiểu không nguyên thủy. Trong các ứng dụng quản lý ta thường xuyên phải đọc và ghi dữ liệu về các đối tượng lên ổ cứng. Các lớp ObjectInputStream và ObjectOutputStream cho phép chúng ta đọc và ghi đối tượng vào file. } 82 . Điều này rất quan trọng bởi vì một đối tượng ObjectOutputStream sẽ không xuất một đối tượng trừ khi đó là một đối tượng Serializable.chế độ ghi và đọc.in Là một đối tượng đặc biệt được tạo ra từ lớp InputStream. XI. Trong đó mode là chế độ mở tập tin: mode = "r" . Lớp này hỗ trợ một số phương thức mới khác với phương thức đã thừa kế từ các lớp DataInput và DataOutput. private String lastName.

public AccountRecord( int acct. String last. } public void setAccount( int acct ) // Ðặt số tài khoản { account = acct. double bal ) // Constructor có tham số { setAccount( acct ). } public String getLastName()// Lấy tên { return lastName. } public void setFirstName( String first ) // Ðặt giá trị cho phần họ đệm { firstName = first.*. } public void setBalance( double bal ) // Đặt giá trị cho balance { balance = bal. } public double getBalance()// Lấy số dư { return balance.txt import java. setLastName( last ). } public void setLastName( String last ) // Ðặt giá trị cho tên { lastName = last. } public int getAccount()// Lấy số tài khoản { return account.io. } public String getFirstName()// Lấy phần họ đệm { return firstName. public class GhiFile 83 . setBalance( bal ). setFirstName( first ). } } Chương trình sau đây sẽ ghi các đối tượng vào file C:\LETI\JAVA\Account. String first.

g. } catch ( IOException ioException ) { System. public void openFile() { try { output = new ObjectOutputStream(new FileOutputStream( "C:\\LETI\\JAVA\\Account.openFile().12).5."Nguyen Van ".12).print("Loi ghi file"). } } // Hàm main public static void main(String[] argvs) { AccountRecord record1= new AccountRecord( 12345.out.close().{ ObjectOutputStream output.exit( 0 ). System.addRecord(record1).addRecord(record2). AccountRecord record2= new AccountRecord( 12346.writeObject( record ). } catch(IOException ex) { System. GhiFile g = new GhiFile(). g."Hai".closeFile(). g.print("Loi mo file"). }} 84 ."Minh". } } public void addRecord(AccountRecord record) // Phương thưc thêm 1 bản ghi vào file { try { output.-5. } // Nếu có lỗi đóng file catch ( IOException ioException ) { System.flush(). } } public void closeFile() // Phương thức đóng file { try { output. g.exit( 1 ). output.txt") ).out."Phan Tien ".

readObject().exit( 1 ).out.} } public static void main(String[] argvs) { DocFile d = new DocFile().valueOf( a. account =String.getBalance()).ObjectInputStream input.io.Chương trình sau đây đọc ra 2 bản ghi vừa được ghi ở chương trình trên và in ra màn hình: import java. } catch(Exception p){} finally {return account. try { AccountRecord a = (AccountRecord)input.io. 85 . public void openFile() // Mở file { try { input = new java.io. public class DocFile { java.close(). } } public void closeFile() //Đóng file { try { input.valueOf( a.txt")).print("Loi mo file").*. System. } } // Phương thức đọc 1 bản ghi public String readFile() { String account="".getLastName() + "\n " + String.exit( 0 ).getFirstName() + "\n " + a. } catch(IOException e) { System.ObjectInputStream(new FileInputStream("C:\\LETI\\JAVA\\Account. } catch ( IOException ioException ) { System.getAccount() ) + "\n " + a.

doc: import java.DataInputStream(new FileInputStream("C:\\P. // Ghi mảng byte này vào một file khác } in.d.io. // Luồng ra hỗ trợ ghi file nhị phân java. // số byte của file if (bytesAvailable > 0) { byte[] data = new byte[bytesAvailable].*.70. in. Chương trình sau đây copy dữ liệu giữa hai file dạng .available(). System.98.out. // Luồng vào hỗ trợ đọc file nhị phân try { in = new java. int bytesAvailable = in.println(d.89. Ha Nam 86 . Tran Thi Mong Mo. 1.write(data).closeFile().read(data). d.openFile().close(). Bùi Thị Thanh Nhàn. Java hỗ trợ cả các thao tác với file nhị phân dùng các đối tượng:  DataOutputStream: Hỗ trợ ghi file ở chế độ nhị phân tức là từng byte. out = new java.io.io.DataOutputStream(new FileOutputStream("C:\\G. Tất nhiên là các file văn bản cũng có thể đọc ghi ở chế độ nhị phân.DataOutputStream out. // Đọc các byte ra một mảng byte out. 1.readFile()). Ha Noi 003.doc")). Truy cập file nhị phân Ngoài các công cụ thao tác trên file văn bản.close().io.doc")). System.println(d. out. Viết một chương trình nhập vào một chuỗi từ bàn phím sau đó ghi chuỗi ra file.io.DataInputStream in. } catch (Exception ex) {} }} Bài tập 1. Nguyen Thu Thuy.out. 2. Cho một file có dữ liệu về thí sinh thi hoa hậu như sau: 001.readFile()).  DataInputStream: Hỗ trợ đọc file ở chế độ nhị phân. }} XII. public class BinaryAccess { public static void main(String[] argvs) { java. 1. Ha Tay 002.

Họ và tên. chiều cao. 1. Viết một chương trình copy dữ liệu từ một file văn bản sang một file văn bản khác.009. 4.78. 87 . Thanh Hoa Các dữ liệu lần lượt mô tả về: Mã số. Quê quán. Viết chương trình copy dữ liệu từ một file ảnh GIF sang một file ảnh GIF khác. Viết một chương trình đọc dữ liệu của file ra và gán mỗi dòng cho một đối tượng HOAHAU. 3. Phan Anh Thu.

Cú pháp để thực hiện điều này như sau: try { // Đoạn chương trình có thể gây ra exception } catch (<Kiểu exception> <tên biến>) { // Đoạn code chạy khi exception xảy ra } finally { // Đoạn code luôn được thực hiện bất kể exception có xảy ra hay không } Một khối try có thể không có hoặc có nhiều khối catch. người sử dụng chương trình muốn rằng chương trình có thể:  Quay lại trạng thái an toàn trước đó và cho phép người dùng thực hiện các công việc khác  Ghi lại các dữ liệu hiện thời và kết thúc chương trình Tuy nhiên điều này là rất khó khăn bởi lỗi có thể đến do một trong các nguyên nhân:  Người dùng nhập dữ liệu sai  Lỗi thiết bị  Lỗi phần cứng như thiếu ổ cứng hay bộ nhớ. chương trình sẽ thực hiện những việc do chính lập trình viên đặt ra. Java cho phép người lập trình quản lý các lỗi xảy ra theo cách khi nó xảy ra. nó có thể “quăng. nếu có một Exception handler . try{ //code có thể throw exceptions 88 .  Xử lý các ngoại lệ từ một thành phần chương trình chưa được quản lý ngoại lệ  Trong các dự án lớn. Xử lý ngoại lệ Khi viết một chương trình nói chung và trong Java nói riêng. Mỗi khối catch xác định một kiểu exception mà nó có thể bắt và chứa đoạn code xử lý trong trường hợp tương ứng.đoạn code xử lý khi lỗi xảy ra – thì Exception này sẽ bị “bắt” (catch) và “được quản lý”(handled). ném”(throws) ra một Exception.Đề tài 7. lỗi có thể xảy ra với rất nhiều lý do. Cơ sở quản lý ngoại lệ trong Java Khi một phương thức không thể hoàn thành nhiệm vụ của nó. I. Các tình huống sử dụng ngoại lệ Việc quản lý các ngoại lệ nên được sử dụng khi:  Một phương thức không thể hoàn thành nhiệm vụ của nó vì một lý do rằng nó không thể điều khiển được mọi chuyện. II. gọi là exception handling. chúng ta gọi đó là một ngoại lệ (exception) – những điều xảy ra khác thường. đưa vào các xử lý ngoại lệ để xử lý theo một cách riêng thống nhất. Trong một đoạn chương trình mà lập trình viên không thể biết trước được liệu có chuyện gì xảy ra làm cho đoạn chương trình đó gây ra lỗi hay không . Khi lỗi xảy ra.

. Java sử dụng cơ chế kết thúc chương trình thay vì cơ chế qua trở lại điểm xảy ra ngoại lệ và tiếp tục. Mỗi khối try bắt buộc phải có một khối catch hoặc finally. Trong một phương thức ta có thể khai báo một mệnh đề throws để phương thức “quăng” ra các ngoại lệ.} catch (MalformedURLException e1) { //code xử lý } catch (UnknownHostException e2) { //code xử lý } catch (IOException e3) { //code xử lý } Sau khối catch cuối cùng. ví dụ: e3. Tại điểm quăng ra ngoại lệ (throw point). lỗi truy cập CSDL SQL. chương trình sẽ tìm đến khối catch có kiểu đối tượng Exception phù hợp để thực hiện. Khi lỗi xảy ra. có thể có hoặc không một khối finally chứa code xử lý bất kể exception có xảy ra hay không.getMessage(). ExceptionType2. ExceptionType3.…Các ngoại lệ trong Java đều kế thừa từ lớp Throwable theo cấu trúc như sau: 89 . sử dụng phương thức getMessage() của các lớp Exception. Ví dụ: int functionName( parameterList ) throws ExceptionType1. Các ngoại lệ này được quăng ra bởi các lệnh throw hoặc việc gọi một phương thức khác trong phương thức này. Cấu trúc cây kế thừa các xử lý ngoại lệ Trong Java có hàng trăm lớp ngoại lệ để “bắt” các lỗi tương ứng như lỗi vào/ra file. Để lấy được thông báo từ hệ thống về lỗi.. { // Thân phương thức } III.

Việc chuyển đối từ chuỗi sang số thực không thành công. Một phương thức cần khai báo ngoại lệ phù hợp: class MyAnimation { . } } Phương thức có thể throws nhiều ngoại lệ nếu cần: 90 .Danh sách các ngoại lệ thường dùng trong Java Ngoại lệ RuntimeException ArthmeticException IllegalAccessException IllegalArgumentException ArrayIndexOutOfBoundsExeption NullPointerException SecurityException ClassNotFoundException NumberFormatException AWTException IOException FileNotFoundException EOFException NoSuchMethodException InterruptedException Ý nghĩa Lớp cơ sở cho nhiều ngoại lệ java. Tuy nhiên. tuy nhiên rất có thể file không tồm tại hoặc là một file rỗng và không có gì để đọc. Đối số không hợp lệ. Khi truy cập đối tượng null. Sử dụng ngoại lệ được kiểm soát Trong phần trên đã bàn về cách sử dụng các exception để bắt các lỗi không được kiểm soát. ví dụ như „chia cho 0‟. Khi gặp lỗi như vậy. Trong phần này chúng ta sẽ xem cách sử dụng ngoại lệ để quản lý các tình huống có thể kiểm soát được. Phương thức yêu cầu không tồn tại. chẳng hạn ở đây là ArrayIndexOutOfBoundsException. Lớp không thể truy cập. Một vấn đề là lập trình viên không biết throws ra ngoại lệ nào hoặc không thể khai báo hết tất cả các ngoại lệ..lang Lỗi về số học. Khi một luồng bị ngắt. Ngoại lệ về AWT Lớp cha của các lớp ngoại lệ I/O Không thể định vị tập tin Kết thúc một tập tin.. Không thể nạp lớp yêu cầu. Lỗi tràn mảng. chương trình sẽ tìm tới vị trí định nghĩa để quản lý lỗi này. Ví dụ trong phương thức khởi tạo sau: public FileInputStream(String name) throws FileNotFoundException Ở đây phương thức nhận một tham số kiểu String như là tên file. Cơ chế bảo mật không cho phép thực hiện. chẳng hạn a[-1] = 0. public Image loadImage(String s) throws IOException { . có 4 tình huống để đưa ra ngoại lệ:  Khi gọi một phương thức có throw một ngoại lệ. IV. chẳng hạn như FileInputStream.  Khi một lỗi bên trong hệ thống như trong JVM hoặc các thư viện động. Các ngoại lệ dạng này được khai báo ở phần đầu các phương thức... sẽ dẫn đến việc kích hoạt một ngoại lệ.  Khi ta xác định được một lỗi và throws một exception bằng một lệnh throw  Khi viết một chương trình bị lỗi.

Đối với các ngoại lệ không được kiểm soát. } } Sau đó...) { if (ch = = -1) // Điểm cuối file { if (n < len) throw new FileFormatException(). chúng kế thừa từ lớp RuntimeException cũng vậy. while (. . ta không nên khai báo chúng.. Ví dụ: class FileFormatException extends IOException { public FileFormatException() {} public FileFormatException(String gripe) { super(gripe). Xây dựng một ngoại lệ Chúng ta có thể tự xây dựng một ngoại lệ để throws trong những trường hợp cụ thể.. public Image loadImage(String s) throws EOFException. } 91 . } } Các ngoại lệ bắt lỗi nội bộ của Java thường không nên được khai báo.. void drawImage(int i) throws ArrayIndexOutOfBoundsException // Không phù hợp { .. Các class ngoại lệ này được kế thừa từ lớp Exception hoặc lớp con của nó như IOException chẳng hạn. nếu chúng ta có kế hoạch để khai báo nó thì tốt nhất là tìm cách để khắc phục không cho chúng xảy ra. ...class MyAnimation { .. MalformedURLException { . ta có thể sử dụng ngoại lệ này trong chương trình: String readData(BufferedReader in) throws FileFormatException { . } } Đối với các ngoại lệ dạng RuntimeException.. Ví dụ: class MyAnimation { . đó là các ngoại lệ kế thừa từ lớp Error vì chúng vượt khỏi tầm kiểm soát của chúng ta. V.

. } VI.. 2. Bắt ngoại lệ khi người dùng nhập vào ký tự hoặc số thực có phần thập phân. 92 . } return s. 3. Chú ý dùng các ngoại lệ để kiểm soát tất cả các tình huống có thể. Khai báo một lớp ngoại lệ để kiểm soát tình huống điểm một sinh viên vượt quá 10 hay tuổi của sinh viên vượt quá 100 trong ứng dụng quản lý sinh viên ở đề tài “Lập trình hướng đối tượng trong Java”. Viết chương trình đọc một file trên ổ đĩa và in ra màn hình. Bài tập 1. Viết chương trình nhập một số nguyên từ bàn phím..

Tất cả các lớp event đều dẫn xuất từ lớp java. nó sẽ gửi thông báo này tới tất cả các bộ lắng nghe sự kiện được đăng ký cho sự kiện đó. chẳng hạn như ActionEvent và WindowEvent.EventObject.Các bộ lắng nghe sự kiện (event listener) Các nguồn sự kiện chính là các đối tượng điều khiển. Khái niệm và cơ sở xử lý sự kiện Bất kỳ chương trình có giao diện đồ họa nào thường hỗ trợ việc kích hoạt các sự kiện từ con chuột hoặc bàn phím.util. chúng có các phương thức để lập trình viên đăng ký các bộ lắng nghe cho chúng. Xử lý các sự kiện trong Java I. Lập trình viên được hoàn toàn quyết định điều gì sẽ xảy ra khi các sự kiện này được kích hoạt.Đề tài 8. Đối với một ngôn ngữ OOP như Java thì toàn bộ thông tin về sự kiện được đóng gói trong một lớp event. Môi trường điều hành sẽ gửi các sự kiện này tới chương trình đang chạy. Khi một sự kiện xảy ra đối với một nguồn sự kiện.Các nguồn của sự kiện (event source) . Mỗi loại sự kiện tương ứng với một lớp dẫn xuất. Trong Java sử dụng một cách tiếp cận dựa trên các khái niệm: . Sau đây là cây phân cấp chỉ sự kế thừa giữa các lớp sự kiện trong Java: 93 .

Tóm lại. // đối tượng lắng nghe JButton button = new JButton("Ok"). . Đối tượng này có cài đặt một phương thức để xử lý sự kiện là actionPerformed. } } Bất cứ khi nào người dùng click chuột vào đối tượng Jbutton trên màn hình. Đối tượng lắng nghe sẽ sử dụng thông tin trong các đối tượng sự kiện để phản ứng với các sự kiện đó. Trong giao diện này có khai báo một phương thức actionPerformed để nhận về một sự kiện ActionEvent: class MyListener implements ActionListener { .addActionListener(listener). khi đó sự kiện cũng được gửi tới tất cả các bộ lắng nghe và tới phương thức actionPerformed của chúng. lấy đối số là đối tượng ActionEvent nhận được.add<sự kiện>Listener(<đối tượng lắng nghe sự kiện>) Ví dụ: ActionListener listener = .. 3. Một nguồn sự kiện là một đối tượng mà có thể đăng ký các đối tượng lắng nghe và gửi cho chúng các đối tượng sự kiện. // Nguồn sự kiện button.. đối tượng listener phải thuộc một lớp có cài đặt giao diện ActionListener. Nguồn sự kiện gửi đối tượng sự kiện tới tất cả các đối tượng lắng nghe được đăng ký cho sự kiện đó. Có thể có nhiều bộ lắng nghe được đăng ký cho một nguồn sự kiện. 4. Cú pháp để đăng ký các đối tượng lắng nghe cho các nguồn sự kiện theo cú pháp sau: <nguồn sự kiện>. một sự kiện ActionEvent được phát sinh và gửi cho đối tượng lắng nghe listener. Ở đây... // đăng ký đối tượng lắng nghe sự kiện Trong đoạn code trên. Sơ đồ sequence cho đoạn code trên như sau: 94 ..Các sự kiện trên được gửi cho các đối tượng lắng nghe tương ứng như: ActionListener MouseMotionListener AdjustmentListener MouseWheelListener FocusListener WindowListener ItemListener WindowFocusListener KeyListener WindowStateListener MouseListener Các nguồn sự kiện khác nhau có thể phát sinh các sự kiện khác nhau. một sự kiện được quản lý dựa trên các khái niệm: 1. . Ví dụ một button (nút bấm) thì phát sinh sự kiện ActionEvent trong khi một cửa sổ lại phát sinh sự kiện WindowEvent. vấn đề còn lại là đối tượng lắng nghe sự kiện phải có một phương thức để nhận về sự kiện từ nguồn sự kiện đăng ký nó và xử lý. Một đối tượng lắng nghe là một biểu hiện của một lớp có cài đặt giao diện lắng nghe sự kiện 2. public void actionPerformed(ActionEvent event) { // Đoạn mã xử ký sự kiện đặt ở đây .

95 .Sau đây là một ví dụ về xử lý sự kiện click cho 3 đối tượng Jbutton: Một Button được tạo ra như sau bằng cách gọi constructor của JButton với một chuỗi nhãn hoặc một ảnh hay cả hai: JButton yellowButton = new JButton("Yellow"). Thêm 3 Button vào 1 panel như sau: Class ButtonPanel extends JPanel { public ButtonPanel() { JButton yellowButton = new JButton("Yellow").gif")). JButton blueButton = new JButton(new ImageIcon("blue-ball. JButton blueButton = new JButton("Blue").

addActionListener(blueAction). add(yellowButton). } public void actionPerformed(ActionEvent e) { setBackground(backgroundColor).JButton redButton = new JButton("Red"). blueButton. ColorAction redAction = new ColorAction(Color. } } Bây giờ chúng ta định nghĩacác bộ lắng nghe cho các Button này gọi là ColorAction như sau: public class ColorAction implements ActionListener { public ColorAction(Color c) { backgroundColor =c. add(blueButton).Blue). } Mỗi đối tượng Button được đăng ký cho bộ lắng nghe này: Class ButtonPanel extends JPanel { public ButtonPanel() { JButton yellowButton = new JButton("Yellow"). add(redButton). add(redButton). Giải pháp ở đây là đưa lớp ColorAction 96 .Red). // Thay đổi màu nền của panel khi Button được click } private Color backgroundColor.addActionListener(redAction). ColorAction yellowAction = new ColorAction(Color. } } Một vấn đề đặt ra là phương thức setBackground() không được định nghĩa trong lớp ColorAction mà chỉ được định nghĩa cho lớp Panel. JButton redButton = new JButton("Red"). ColorAction blueAction = new ColorAction(Color. add(blueButton). redButton.addActionListener(yellowAction).Yellow). yellowButton. JButton blueButton = new JButton("Blue"). add(yellowButton).

addActionListener(yellowAction).addActionListener(redAction). this.Yellow). ColorAction yellowAction = new ColorAction(Color. public class testPanel extends JFrame { public testPanel() { ButtonPanel pn = new ButtonPanel(). Class ButtonPanel extends JPanel { public ButtonPanel() { JButton yellowButton = new JButton("Yellow"). JButton redButton = new JButton("Red"). yellowButton.thành lớp nội của lớp ButtonPanel. } public static void main(String[] argvs) 97 .Red). } } Chương trình sau đây kiểm tra sự thực hiện đáp ứng các sự kiện vừa thiết kế ở trên: import javax. add(yellowButton). ColorAction blueAction = new ColorAction(Color.add(pn).swing.JFrame.addActionListener(blueAction). ColorAction redAction = new ColorAction(Color. add(blueButton). add(redButton). JButton blueButton = new JButton("Blue").Blue). redButton. // Thay đổi màu nền của panel khi Button được click } private Color backgroundColor. ta có thể truy cập các phương thức của lớp Panel (được ButtonPanel kế thừa) như setBackground chẳng hạn. khi đó trong lớp ColorAction. // Đăng ký bộ lắng nghe sự kiện blueButton. } private class ColorAction implements ActionListener { public ColorAction(Color c) { backgroundColor =c. } public void actionPerformed(ActionEvent e) { setBackground(backgroundColor).

} public void actionPerformed(ActionEvent event) { if (event.{ testPanel p = new testPanel(). if (event. Muốn vậy. II. phương thức actionPerformed sẽ có sự hành xử khác nhau.addActionListener(this). add(blueButton). blueButton.addActionListener(this). add(yellowButton).RED). yellowButton.*.swing.addActionListener(this). lớp chứa các nguồn sự kiện phải cài đặt giao diện ActionListener. p. redButton = new JButton("Red"). public class ButtonPanel extends JPanel implements ActionListener { JButton yellowButton. } } Thông thường. import java.awt.getSource()==yellowButton) setBackground(Color.YELLOW). Truy cập thông tin sự kiện Một phương pháp khác để lập trình sự kiện đó là gán cho tất cả các đối tượng nguồn sự kiện chung một đối tượng lắng nghe. các lớp lắng nghe sự kiện có thể được cài đặt ngay trong phương thức addActionListener như sau: yellowButton. JButton redButton. import javax. blueButton = new JButton("Blue"). Làm như vậy ta không cần thiết kế riêng một lớp ColorAction. } }). add(redButton).*.400).YELLOW). Tùy theo thông tin về sự kiện nhận được. p. public ButtonPanel() { yellowButton = new JButton("Yellow").getSource()==redButton) setBackground(Color.event. redButton.setSize(300. JButton blueButton. 98 .setVisible(true).addActionListener( new ActionListener() { public void actionPerformed(ActionEvent event) { setBackground(Color.

Đối tượng listener bắt buộc phải thuộc một lớp có cài đặt giao diện WindowListener. bản thân lớp component ButtonPanel đóng vai trò là lớp lắng nghe sự kiện vì nó có cài đặt giao diện ActionListener. ta cũng qua các bước căn bản sau: WindowListener listener = new .BLUE). đại diện cho đối tượng ngầm định của chính lớp ButtonPanel.exit(0).if (event. } public void windowOpened(WindowEvent e) {} public void windowClosed(WindowEvent e) {} public void windowIconified(WindowEvent e) {} public void windowDeiconified(WindowEvent e) {} public void windowActivated(WindowEvent e) {} public void windowDeactivated(WindowEvent e) {} } 99 . Tuy nhiên. ta chỉ việc sử dụng biến this.. ta chỉ viết code cho phương thức nào ta xử lý mà thôi. Trong đó frame là một đối tượng của lớp JFrame..getSource()==blueButton) setBackground(Color. Phần này ta sẽ xem xét các sự kiện xảy ra đối với bản thân một window. Do đó. khi đăng ký đối tượng lắng nghe cho các Button. void windowActivated(WindowEvent e). } Do đó các lớp cài đặt giao diện này phải khai báo định nghĩa tất cả các phương thức trên. Muốn bắt các sự kiện của window. ví dụ: class Terminator implements WindowListener { public void windowClosing(WindowEvent e) { System. void windowDeactivated(WindowEvent e). Tuy nhiên phương pháp này sẽ trở nên khó dùng khi trên panel có nhiều đối tượng nguồn sự kiện. III. // thu nhỏ của sổ void windowDeiconified(WindowEvent e).. là đối tượng nguồn sự kiện phát sinh các sự kiện WindowEvent.. void windowClosing(WindowEvent e). } } Trong ví dụ trên. Xử lý các sự kiện trên window Phần trên đã cho thấy cách thức chúng ta làm việc với các nguồn sự kiện là các đối tượng nằm trong một window. Các đối tượng Button bây giờ cũng phải khai báo là biến thành phần của lớp vì chúng được truy cập trong 2 phương thức khác nhau. Cấu trúc của giao diện này như sau: public interface WindowListener { void windowOpened(WindowEvent e). void windowIconified(WindowEvent e). frame. void windowClosed(WindowEvent e).addWindowListener(listener).

IV. Các lớp thích nghi
Ta thấy rằng việc khai báo đầy đủ 7 phương thức, có những phương thức không xử lý gì cả làm cho chương trình không được tối ưu. Giải pháp ở đây sẽ là định nghĩa một lớp trung gian, khai báo cài đặt giao diện WindowListener với đầy đủ 7 phương thức nhưng các phương thức này cũng không làm gì cả. Các lớp muốn cài đặt nội dung cho một sự kiện chỉ việc khai báo kế thừa lớp này và định nghĩa chồng phương thức cần thiết. Các lớp có vai trò trung gian như vậy gọi là các lớp thích nghi. Với mỗi giao diện lắng nghe, ta có một lớp thích nghi tương ứng. Ví dụ: WindowListener có lớp thích nghi WindowAdapter, MouseListener có MouseAdapter. Các lớp thích nghi thường dùng là: FocusAdapter MouseMotionAdapter KeyAdapter WindowAdapter MouseAdapter class Terminator extends WindowAdapter { public void windowClosing(WindowEvent e) { System.exit(0); } } Vấn đề là các lớp window thường phải khai báo kế thừa từ JFrame rồi nên không thể khai báo kế thừa thêm lớp WindowAdapter. Lúc này, kỹ thuật định nghĩa lớp nội nặc danh được phát huy: frame.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent event) { System.exit(0); } public void windowIconified(WindowEvent e) {System.exit(0);} } ); Đoạn code này thực hiện các công việc sau: 1. Định nghĩa một class nặc danh kế thừa lớp WindowAdapter 2. Thêm 2 phương thức windowClosing và windowIconified cho lớp nặc danh đó 3. Kế thừa 5 phương thức còn lại từ WindowAdapter 4. Tạo ra một đối tượng của lớp đó, đối tượng cũng không có tên 5. Gửi đối tượng này cho phương thức addWindowListener Ta có thể định nghĩa chồng nhiều hơn một phương thức của WindowAdapter. Tất nhiên là không phải khi nào ta cũng phải sử dụng lớp nội nặc danh. Một cách làm khác là khai báo một lớp (thường là lớp nội) dạng như class Terminator ở trên, sau đó đăng ký lắng nghe sự kiện cho frame mà không cần một đối tượng có tên rõ ràng của Terminator: frame.addWindowListener(new Terminator()); Để kết thúc đề tài này ta liệt kê các phương thức xử lý sự kiện như bảng sau:

100

Interface ActionListener

Methods actionPerformed

Parameter/Accessors ActionEvent
 

Nguồn sự kiện AbstractButton JComboBox JTextField Timer JScrollbar

getActionCommand getModifiers

AdjustmentListener

adjustmentvalueChanged AdjustmentEvent
  

getAdjustable getAdjustmentType getValue AbstractButton JComboBox

ItemListener

ItemstateChanged

ItemEvent
  

getItem getItemSelectable getStateChange Component

FocusListener

FocusGained focusLost

FocusEvent

isTemporary Component

KeyListener

keyPressed keyReleased keyTyped

KeyEvent
    

getKeyChar getKeyCode getKeyModifiersText getKeyText isActionKey Component

MouseListener

mousePressed mouseReleased mouseEntered mouseExited mouseClicked

MouseEvent
    

getClickCount getX getY getPoint TRanslatePoint Component

MouseMotionListener

mouseDragged mouseMoved

MouseEvent

101

Interface MouseWheelListener

Methods mousewheelMoved

Parameter/Accessors MouseWheelEvent
 

Nguồn sự kiện Component

getWheelRotation getScrollAmount Window

WindowListener

windowClosing windowOpened windowIconified windowDeiconified windowClosed windowActivated windowDeactivated windowGainedfocus windowlostFocus

WindowEvent

getWindow

WindowFocusListener

WindowEvent

Window

getOppositeWindow Window

WindowStateListener

WindowStateChanged

WindowEvent
 

getOldState getNewState

V. Xử lý các sự kiện chuột Các sự kiện với chuột được xử lý bởi giao diện MouseListener. Khi một nguồn sự kiện được kích hoạt bởi việc click chuột, các phương thức xử lý cho các sự kiện tương ứng được liệt kê trong bảng trên, đặc biệt hay dùng là mouseClicked(). Thông thương ta cũng không cài đặt xử lý cho tất cả các sự kiện này nên ta không cài đặt giao diện MouseListener mà khai báo một lớp nội nặc danh kế thừa từ lớp thích nghi MouseAdapter. Giả sử có một đối tượng JFrame tên là frame, sau đây là một ví dụ quản lý sự kiện click chuột trên nó: frame. addMouseListener( new MouseAdapter() { public void mouseClicked(MouseEvent e) // Mac dinh la chuot trai { // Kiem tra neu la chuot phai duoc click if( (e.getModifiers() & InputEvent.BUTTON3_MASK)== InputEvent.BUTTON3_MASK) // hien thi mot popup menu tai vi tri click jp.show(getContentPane(),e.getX(),e.getY()); } } ); Tham khảo thêm tại: http://java.sun.com/docs/books/tutorial/uiswing/events/handling.html

102

và http://java.sun.com/docs/books/tutorial/uiswing/events/mouselistener.html

Bài tập
1. Viết chương trình xử lý sự kiện chuột click trên các Botton, nếu là chuột trái thì thông báo là “Bạn vừa click chuột trai”, nếu là chuột phải thì thông báo “Bạn vừa click chuột phải”. 2. Viết chương trình sau khi chọn một Button trên màn hình, nhấn phím x thì chương trình kết thúc.

103

Đề tài 9. Applet
Applet là một trong những kỹ thuật vượt trội của Java so với các ngôn ngữ khác. Một Applet là một chương trình Java được nhúng vào trong các trang web, nó đứng một vị trí độc lập bên cạnh các phần khác của trang web.

I. Xây dựng một Applet đơn giản
1. Soạn thảo một tệp có tên “Hello.java” như sau: import java.applet.Applet; //khai báo thư viện import java.awt.Graphics; //Khai báo đồ hoạ public class Hello extends Applet { //cài đặt phương thức cho Applet public void paint(Graphics g){ g.drawString("Hello!", 50, 25); } 2. Biên dịch tệp Hello.java 3. Soạn thảo một trang HTML có tên hello.htm <html><body> <applet> <applet code="Hello.class" width=150 height=25> </applet> </body></html> 4. Đặt file Hello.class và hello.htm vào trong cùng một thư mục 5. Mở file hello.htm. Tuy nhiên để các applet có thể chạy được, nó cần một JVM trên máy cục bộ. Để có được JVM cho các trình duyệt ta cần cài phiên bản Java lên máy tính cục bộ và tích hợp vào trình duyệt như một plug-in. Trong các phiên bản Java gần đây, người lập trình có thể sử dụng thư viện swing nằm trong gói javax.swing để có được giao diện GUI thống nhất trên mọi hệ thống. Các lớp trong swing có tên gọi khác so với các lớp trong awt bởi thêm ký tự đầu tiên “J”.

II. Cấu trúc cơ bản và vòng đời của một Applet
Một chương trình Applet đầy đủ sẽ bao gồm các thành phần như sau: import java.applet.Applet; public class myApplet extends Applet{ public void init(){ ...... } public void start(){ ...... } public void stop() { ...... } public void destroy() { ...... } .... //Các phương thức khác } Nếu dùng JApplet thì ta có khai báo phần đầu như sau: import javax.swing.JApplet; public class myApplet extends JApplet{…}

104

// Lưu tọa độ điểm hiện tại public void init() { curentPoint = new Point(this. Do đó. // đặt màu nền của applet } public void start() { this. chúng ta không phải khi nào cũng cài đặt đầy đủ 4 phương thức mà tùy theo nhu cầu. import java. Giai đoạn này được bắt đầu ngay sau khi thẻ <param> nằm trong thẻ <applet> được xử lý.*. 4. 3. Khi viết một applet. Giai đoạn stop: Được thực hiện khi người dùng rời khỏi trang web chứa applet.this. Nó cũng được gọi bất cứ khi nào người dùng chuyển sang một trang web khác rồi quay lại trang có applet. } public void drawOnApplet(Point p1.getPoint()).x.Vòng đời của một Applet được đánh dấu bởi các sự kiện diễn ra ở mỗi giai đoạn.drawLine(p1. 2.setBackground(Color.*.event. Giai đoạn start: Được thực hiện ngay sau khi giai đoạn init được thực hiện xong. Giai đoạn destroy: Được thực hiện khi người sử dụng tắt trình duyệt.getGraphics(). this.e. Giai đoạn init: Thực hiện các công việc khởi tạo một Applet.CYAN).getWidth()/2. } } ).p2.addMouseListener( new MouseAdapter() { public void mouseClicked(MouseEvent e) { drawOnApplet(curentPoint. Các hành động như thêm các thành phần giao diện người dùng GUI được thực hiện ở đây.awt. public class AppletSample extends Applet { Point curentPoint. code nằm trong start có thể được thực hiện nhiều lần trong khi code trong init chỉ được thực hiện 1 lần. curentPoint = e.y). lập trình viên cần nắm được ý nghĩa của từng giai đoạn để có thể viết code điều khiển Applet: 1.y.p2.x. Do đó. import java.p1. g. import java.getPoint().applet. Point p2) { Graphics g = this. code nằm trong stop cũng có thể được thực hiện nhiều lần.awt.*.getHeight()/2). } } 105 . Ví dụ sau xây dựng một applet cho phép vẽ liên tiếp bắt đầu từ vị trí giữa applet.

*. import java. frame. import java.  Các applet được nạp từ hệ thống tập tin cục bộ sẽ không bị các giới hạn của các applet được nạp từ mạng xuống.  Có thể gọi đến các phương thức toàn cục của các applet khác trên cùng trang web.*.…  Tất cả các cửa sổ trình duyệt có applet được tải về đều có thông báo. password. calcButton.setTitle("Calculator"). Các nguyên tắc về an ninh của một applet là:  Applet không bao giờ thực hiện một chương trình của máy cục bộ.  Applet không thể giao tiếp với các máy tính khác trên mạng trừ máy tính mà nó được download về. frame.awt. ký tự phân tách file.setSize(200.III.  Applet cũng có những khả năng như:  Tạo kết nối đến máy đang chạy nó. // Thêm một Button để ẩn/ hiện frame pop-up JButton calcButton = new JButton("Calculator").awt. public class PopupCalculatorApplet extends JApplet { public void init() { // Tạo một frame với một cửa sổ panel final JFrame frame = new JFrame(). Applet không thể tìm thấy các thông tin cá nhân như email.addActionListener(new ActionListener() { 106 . An ninh và khả năng của Applet Vì applet được download từ xa và thực hiện trên máy tính cụ bộ nên vấn đề về an ninh được quan tâm đặc biệt.swing.  Applet không thể đọc và ghi dữ liệu lên máy tính cục bộ  Applet không thể tìm thấy thông tin gì về máy tính cuc bộ. Những yêu cầu về an ninh của applet là rất quan trọng. import javax.*.  Không nhất thiết là các applet sẽ ngừng lại khi ta thoát khỏi các trang web chứa nó. Ứng dụng Applet với của sổ Popup Với Applet chúng ta hoàn toàn có thể có thêm các cửa sổ pop-up để mở rộng không gian làm việc. trừ các thông tin như phiên bản Java. tên và phiên bản hệ điều hành.  Applet dễ dàng dùng các siêu văn bản hiển thị. đường dẫn. 200). Sau đây là một Japplet có thể mở một Frame mới. IV. Applet có thẻ giao tiếp với các applet khác trên trang web cũng như với các đối tượng khác trên trang web thông qua cơ chế riêng. Trong một số trường hợp ta có thể cấu hình để applet được tin cậy và có thể truy cập vào máy tính cục bộ giống như một chương trình đang chạy trên máy tính đó. add(calcButton).event.

class" width="200" height="200"> <param name="font" value="Helvetica"/> <param name="size" value="24"/> 107 .class". Các applet không thể thay đổi kích thước khi đã chạy. archive: Chứa tên các gói chương trình hoặc tài nguyên khác được tải về kèm theo applet. Tên này là tương đối so với giá trị codebase hoặc với thư mục hiện hành nếu không có codebase.class" width="300" height="100"> Thong tin duoc hien thi khi applet khong hien thi </applet> Sau đây ta sẽ tìm hiểu các thuộc tính của applet: Các thuộc tính về vị trí:  height: Chiều cao của applet.corejava/CoreJavaClasses.mycompany. texttop.jar" width="100" height="150"> object: Chứa tên file đã được tuần tự hóa của một applet.MyApplet.. name: Tên của applet. baseline. top.isVisible()). middle. hoặc: code="com. } } V.class" archive="CalculatorClasses.  width: Chiều rộng của applet  align: Xác định vị trí của applet so với các văn bản xung quanh nó.codebase: Là một thuộc tính tùy chọn để xác định đường dẫn tuyệt đối nơi chứa class ở giá trị code. Khi đó applet cần có tên để truy cập. absbottom.jar.code: code : Thuộc tính này cho biết tên của class chứa chương tình applet.setVisible(!frame. Các giá trị của align có thể là: left.public void actionPerformed(ActionEvent event) { frame. Ngoài ra Java cho phép ta định nghĩa các tham số cho applet thông qua các thẻ <param> Ví dụ: <applet code="FontParamApplet. bottom. Các thuộc tính về chương trình nguồn. . } }). right. Ví dụ: nếu applet có tên MyApplet.class" cũng được chấp nhận. Các thẻ HTML của Applet Một khai báo applet trong trang HTML thường có dạng: <applet code="NotHelloWorldApplet.mycompany thì đường dẫn phải là: code="com/mycompany/MyApplet.class được đặt trong gói com. Ví dụ: <applet code="CalculatorApplet. absmiddle. Đường dẫn phải phù hợp với đường dẫn gói của class applet. vspace và hspace. Trong các trình duyệt của Netscape hoặt Windows đều cho phép applet giao tiếp với các đối tượng javascript khác trên trang web. Các gói chương trình được nén ở dạng file JAR và được đặt cách nhau bởi dấu .

} } VI. int height): Vẽ đường oval. int yCoor. int offset. int xCoor. int archeight): Vẽ hình chữ nhật có bo góc. int y1. int offset.  Phương thức repaint() được dùng khi cửa sổ cần cập nhật lại. int width.  drawRoundRect(int xCoor. int x2. Chú thích các tham số: array: Mảng các ký tự. xCoor: Toạ độ X. yCoor: Toạ độ Y.  drawLine(int x1. int width.Trong đó: width là Chiều rộng của hình. height là Chiều cao của hình..parseInt(getParameter("size")). yCoor: Toạ độ Y.  public void update(Graphics g) {. int yCoor): xuất các ký tự. Các phương thức. . thường các applet dùng paint() để biểu diễn các hoạt động của mình trên trang web. int height): Vẽ hình chữ nhật.}: là phương thức ta dùng sau khi thực hiện pain() nhằm làm tăng hiệu quả vẽ.  getDocumentBase(): cho biết địa chỉ dạng URL của thư mục chứa tập tin HTML chứa applet.  getLocale(): Xác định vị trí applet. int height.  getImage(URL url. int yCoor. length: Số các ký tự cần được vẽ. int yCoor.  drawBytes(byte array[ ]. String name): trả về một đối tượng ảnh hiển thị trên nền.  drawChars(char array[ ].CLASS của applet. int length. int length. nơi các ký tự cần được vẽ.. int fontSize = Integer. y1) đến B(x2. lập trình đồ họa và bắt sự kiện của applet public void paint(Graphics g) {. int width. int yCoor.. nơi các ký tự cần được vẽ. y2).Vị trí offset hay vị trí bắt đầu.  drawOval(int xCoor. int width.. int yCoor): xuất các byte ra.  fillRect(int xCoor.}: Là phương thức hiển thị cơ bản.. int height): Vẽ hình chữ nhật đặc. int yCoor.</applet> Khi đó trong chương trinh applet. Ngoài ra Applet còn thừa hưởng các phương thức từ lớp AWT.  getCodeBase(): Cho biết địa chỉ dạng URL của thư mục chứa tập tin . int width. int xCoor. offset: Vị trí bắt đầu..  showStatus(String st): hiển thị xâu st trên thanh trang thái.. length: Số byte cần vẽ.  drawRect(int xCoor. ta có thể lấy ra để sử dụng: public class FontParamApplet extends JApplet { public void init() { String fontName = getParameter("font").  108 .. int height): Vẽ hình oval đặc. xCoor: Toạ độ X. String name): cho đối tuợng audio. int y2): Vẽ đường thẳng từ A(x1.  getAudioClip(URL url.Trong đó array: Mảng các byte. Phương thức này chỉ cần một tham số là đối tượng của lớp Graphics. int arcwidth.  fillOval(int xCoor. nơi các ký tự được vẽ.

int height. y[ ]: Mảng lưu trữ toạ độ y của các điểm. int arcwidth.cyan Color. int height. int archeight): Vẽ hình cung đặc. arcwidth: Góc bắt đầu.black Color. height: Chiều cao của cung được vẽ.magenta  109 .white Color. int y[ ]. Font.fillRoundRect(int xCoor.yellow Color.BOLD. yCoord: Toạ độ y. Font. int yCoord. Ví dụ.  drawArc(int xCoord. Bảng một số màu cơ bản: Color. yArray: Mảng lưu trữ toạ độ y của các điểm. int y[ ]. Trong đó: x[ ]: Mảng lưu trữ toạ độ x của các điểm. int arcwidth.red Color.PLAIN.  fillPolygon(int x[ ]. int numPoints):Vẽ đa giác. int height. int width. int arcwidth. archeight: làm tròn góc trên đỉnh và góc đáy của hình chữ nhật. (Font. Trong đó: xCoord: Toạ độ x. int height. int yCoord. arcwidth = 20 có nghĩa là hình chữ nhật được làm tròn cạnh trái và cạnh phải mỗi cạnh 10 pixel. int archeight): vẽ hình chữ nhật bo góc đặc.  fillArc(int xCoord. int numPoints): Vẽ đa giác đặc.gray Color. Font. int yArray[ ].blue Color.  drawPolyline(int xArray[ ]. totalPoints: Tổng số điểm cần vẽ. Trong đó: arcwidth: làm tròn góc trái và góc phải của hình chữ nhật. numPoints: Tổng số điểm cần vẽ.green Color.ITALIC)  drawPolygon(int x[ ].darkgray Color. int archeight): Vẽ hình cung. archeight: Độ rộng của cung (góc của cung) so với góc ban đầu.  draw3Drect(int xCoord.pink Color. int width.orange Color. int yCoord.BOLD. setColor(Color c): Đặt màu vẽ. boolean raised): Vẽ hình chữ nhật 3D. 15)): Đặt Font cho chữ. width: Chiều rộng của cung được vẽ. int totalPoints): Vẽ nhiều đường thẳng Trong đó: xArray: Mảng lưu trữ toạ độ x của các điểm. int width. int yCoor.  setFont(new Font(“Times Roman”.lightgray Color. int width.

4. Các lớp GUI trong swing có thêm tiền tố “J” so với các lớp trong AWT. Một giao diện người dùng được hình thành từ các phần tử của GUI.4. 2.  Đồ hoạ (Graphics) và các tính năng vẽ (draw).  Trình quản lý cách trình bày (Layout manager).*.  Sự kiện (Event).  Thành phần (Component).  Phông chữ (Font). Sơ đồ phân cấp thừa kế các đối tượng GUI trong swing như sau: 110 . Thêm phần tử vào giao diện trên màn hình. Java phát triển một thư viện mở rộng mới với đa số các lớp GUI kế thừa từ AWT nhưng có khả năng di động tốt hơn. Chỉ ra nó nằm ở đâu. Một phần tử GUI được thiết lập bằng cách sử dụng các thủ tục: 1. Lập trình giao diện đồ họa GUI I.Đề tài 10. chúng ta sẽ xét các thành phần GUI trong swing. Từ phiên bản 1. Giới thiệu AWT Abstract Windows Toolkit – AWT: Là thư viện của Java cung cấp cho lập trình viên các giải pháp giao diện người dùng đồ hoạ (Graphical User Interface . 3. các thành phần này có thể là:  Vật chứa (Container). Để làm việc với các đối tượng GUI chúng ta cần nhập gói java.GUI) thân thiện. AWT cung cấp các thành phần khác nhau để tạo GUI hiệu quả.awt. Sau đây. Xác định sự xuất hiện ban đầu của đối tượng. Tạo đối tượng.

f. Ví dụ sau tạo một đối tượng JPanel và đặt vào nó một đối tượng nút bấm JButton. JApplet.  Lấy tiêu đề của JFrame: public String getTitle().  Xác định JFrame đang ở tình trạng nào: public boolean isResizable(). int height).1 JFrame Tạo đối tượng khung chứa JFrame bằng phương thức khởi tạo: void JFrame(). f. Ví dụ: JFrame frame1 = new JFrame(). trong đó: b = true thì Frame có thể thay đổi kích thước. 111 .show().  Co dãn JFrame: public void setResizable(boolean b). JFrame frame2 = new JFrame("Cua so Frame"). để tạo các ứng dụng windows.  Đưa cửa sổ hiện ra màn hình: frame1. public class FrameSample { public static void main(String[] argvs) { JFrame f = new JFrame().*. để nhóm các đối tượng con lại và sắp xếp theo cách thích hợp.khung chứa đơn giản nhất. b = false cho ẩn. nó là cửa sổ hộp thoại đưa ra những lời thông báo..  Thay đổi tiêu đề cho JFrame: frame1.  JScrollPanel .setSize(int width.2 JPanel JPanel không thể nhìn thấy trực tiếp. . II.setTitle(String newTitle).dispose(). Tạo khung chứa JPanel bằng phương thức khởi tạo: JPanel panel1 = new JPanel().  JFrame . nó là đối tượng dùng để chứa các thành phần GUI trên màn hình. Vật chứa thường được sử dụng là:  JPanel . frame1.setVisible(true).400).II. trong đó: b = true cho hiển thị. II.  Thay đổi biểu tượng JFrame: public setIconImage(Image img). b = false thì không đổi.  Bỏ hoàn toàn đối tượng JFrame: frame1.khung chứa như Panel nhưng có hai thanh trượt.là cửa sổ nhưng không đầy đủ chức năng như Frame. Tạo Frame với tiêu đề bên trên: void JFrame(String FrameTitle).swing.  JDialogs . } } Một số phương thức hay sử dụng:  Đặt lại kích thước cho JFrame: frame1.setVisible(boolean b)..là một cửa sổ như mọi ứng dụng của windows. Vật chứa (Container) Là vùng mà ta có thể đặt các thành phần (component) của giao diện. Một vật chứa có thể chứa nhiều phần tử. import javax. Do đó chúng ta cần gắn JPanel vào đối tượng nào đó như: JFrame.setSize(400.

swing. Lấy và thay đổi kích thước JDialog: public setResizable(boolean). true) Tạo JDialog có tiêu đề định trước: public JDialog(Frame parentWindow. public class FrameSample { public static void main(String[] argvs) { JFrame f = new JFrame(). Các đặc điểm thường sử dụng với đối tượng JDialog thể hiện tương tự với JFrame.*. f.400).setSize(400. p.setVisible(true). nhưng ít chức năng hơn. Giấu cửa sổ JDialog ta dùng phương thức: hide(). import java. String getTitle().3 JDialog Như JFrame. Đưa đối tượng JDialog ra màn hình bằng phương thức show().quyết định xem JDialog được tạo ra ở dạng nào: isModal = true cho modal còn isModal = false cho non-modal. public FrameSample() // Constroctor { 112 . boolean isResizable() Đặt và lấy tiêu đề của JDialog: void setTitle(String). } } II. Ví dụ: JDialog myDialog = new JDialog(myWindow. String title.add(p).swing. JPanel p = new JPanel(). // gắn JPanel vào JFrame f. Xác minh một JDialog đang thuộc dạng nào ta gọi phương thức: public boolean isModal() Chương trình sau đây sẽ ẩn hoặc hiện một Jdialog mỗi khi nhất vào một nút bấm: import javax.*.event. Ta có thể tạo JDialog dưới hai hình thức:  modal: là cửa sổ JDialog khi thực hiện sẽ khoá chặt các cửa sổ khác. public class FrameSample extends JFrame { private JDialog d. còn được gọi là popup-window.awt.awt. import java.import javax. Ẩn hiện JDialog ta còn có phương thức: setVisible(boolean). boolean isModal) JDialog không thể gắn với Applet.  non-modal: ngược lại với modal. boolean isModal). cửa sổ này thích ứng với các thao tác mang tính tuỳ biến. trong đó: isModal . muốn đưa ra một JDialog từ JApplet ta phải tạo ra một JFrame giả tạo.add(new JButton("OK")). Cửa sổ này thường yêu cầu một tác vụ nào đó cần phải hoàn thành ngay. Cách tạo khung chứa JDialog từ phương thức khởi tạo: public JDialog(JFrame parentWindow.*.*. f.

JScrollPane được ứng dụng trong các danh sách chọn."Day la Jdialog".isVisible()).1 Nút nhấn Cách tạo nút nhấn Ta gọi phương thức khởi dựng: public Button(String label) label là tên nhãn của nút nhấn Ví dụ: Button nutOK = new Button("OK"). JButton: Đối tượng nút bấm JcheckBox: Đối tượng nút chọn. } } II. fs.4 JScrollPane Đây không phải là một cửa sổ nhưng có tính chất như khung chứa JPanel dùng để chứa các đối tượng.false). add(p).setSize(100. JPanel p = new JPanel().d = new JDialog(this. } } ).setVisible(true). Tính chất khác là khi đối tượng nó chứa quá lớn thì JScrollPane sẽ xuất hiện thanh trượt đứng và ngang ở hai bên viền để ta có thể xem được toàn bộ.setVisible(!d. Để đổi tên nhãn cho nút nhấn ta gọi phương thức public void setLabel(String newLabel).400). Đư nút nhấn vào Applet hay cửa sổ chương trình bằng lệnh: add(nutOK). III. d.setSize(400. JtextField: Chỉ một đối tượng cho phép nhập dữ liệu từ bàn phím.add(b). fs. JcomboBox: Đối tượng ComboBox Jlist: Danh sách JPanel: Nơi đặt các thành phần GUI nói trên. Để xem tên nhãn hiện tại của nút nhấn. } public static void main(String[] argvs) { FrameSample fs = new FrameSample().addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { d. Giới thiệu về các thành phần GUI cơ bản        Jlabel: Chỉ một vùng hiển thị văn bản hoặc các icon. b. III. JButton b = new JButton("Xem/Tat mot JDialog"). p.100). ta gọi phương thức public String getLabel() 113 .

public class LabelTest extends JFrame { private JLabel label1.setToolTipText( "This is label2" ). Label. bug. label3. import java.LEFT.*. int align) Một số phương thức hay sử dụng: setText(String nameLabel): Đặt lại nội dung mới cho nhãn. label2 = new JLabel( "Label with text and icon".RIGHT: những giá trị căn lề. Label.LEFT ).add( label1 ).*.setLayout( new FlowLayout() ).*. SwingConstants. nutOK. label1. label2. // Tạo giao diện GUI public LabelTest() { super( "Testing JLabel" ). // constructor của JLabel label1 = new JLabel( "Label with text" ). // thêm vào container // Tạo Jlabel với icon hoặc text Icon bug = new ImageIcon( "bug1. Vấn đề này chúng ta đã xem xét trong phần xử lý các sự kiện III.gif" ). // Contructor của JFrame // Lấy đối tượng pane của một JFrame Container container = getContentPane().CENTER.2 Nhãn (Label) Tạo nhãn không có nội dung gì: public Label() hoặc tạo nhãn có nội dung: public Label(String nameLabel). label2. Xem nhãn đang được căn lề ở chế độ nào: public int getAlignment().Ví dụ: Button nutOK = new Button(). container.setToolTipText( "This is label1" ). Thiết lập lại chế độ căn lề: public void setAlignment(int align) throws IlligalArgumentException Sau đây là ví dụ sử dụng JLabel: // Minh họa về JLabel // Nhập các gói thư viện import java.swing. container. 114 .awt. // Gói Java mở rộng import javax. Lấy nội dung hiện hành của nhãn: public String getText(). Label.setLabel("OK"). Sử dụng nút nhấn Khi kích chuột vào nút nhấn sẽ thực hiện một công việc nào đó. // hiển thị khi di chuột đến container. hoặc thêm chế độ căn lề: pubic Label(String name.add( label2 ).event.awt.

setVisible( true ).setIcon( bug ). label3. } // hàm main public static void main( String args[] ) { LabelTest application = new LabelTest(). ta dùng phương thức: addItemListener(ItemListener L) Để loại bỏ lắng nghe đó ta dùng phương thức: removeItemListener(ItemListener L) // Java core packages import java. 115 .  public Checkbox(String cbLabel . Nhóm các ô đánh dấu trở thành nút chọn. label3. Nếu muốn thiết lập trạng thái.// JLabel không tham số label3 = new JLabel().setHorizontalTextPosition( SwingConstants.EXIT_ON_CLOSE ).setText( "Label with icon and text at bottom" ).  public Checkbox(String cbLabel. boolean state. import java. application. Xử lý tình huống khi ô đánh dấu thay đổi trạng thái: Để lắng nghe ô đánh dấu. container. boolean state): dùng để tạo ô đánh dấu có nhãn với trạng thái đánh dấu ban đầu.*.CENTER ).setDefaultCloseOperation( JFrame.add( label3 ).  public Checkbox(String cbLabel.  public Checkbox(String cbLabel): tạo ô đánh dấu với một nhãn cbLabel gắn kèm. Kiểm tra và thiết lập trạng thái: Để kiểm tra một ô có được đánh dấu không ta dùng phương thức: public boolean getState(). label3. nút tạo ra được nhóm trong nhóm g. CheckboxGroup g).BOTTOM ). label3. CheckboxGroup g.awt.event. boolean state): Tạo ô đánh dấu với một nhãn cbLabel gắn kèm với trạng thái ban đầu của ô đó.*. Ta có thể tạo nút đánh dấu theo 5 phương thức khởi dựng:  public Checkbox(): tạo ô đánh dấu không có nhãn.3 Nút đánh dấu (checkbox) Một nút đánh dấu có hai phần: nhãn và dấu biểu hiện trạng thái.setVerticalTextPosition( SwingConstants. } } III.awt. 170 ).setToolTipText( "This is label3" ). ta dùng phương thức: setState(boolean state). setSize( 275. label3.

setSize( 275.swing.PLAIN. container. // lấy pane Container container = getContentPane().add( italic ). field. public class CheckBoxTest extends JFrame { private JTextField field. private int valItalic = Font.addItemListener( handler ).*. container.setFont( new Font( "Serif". 20 ).PLAIN.PLAIN. italic.setDefaultCloseOperation( JFrame. // Thiết lập GUI public CheckBoxTest() { super( "JCheckBox Test" ).add( field ). 14 ) ). Font.add( bold ). application. setVisible( true ). // Đáp ứng sự kiện chọn ô public void itemStateChanged( ItemEvent event ) { // xử lý chọn ô chữ đậm if ( event. // tạo đối tượng checkbox bold = new JCheckBox( "Bold" ).EXIT_ON_CLOSE ).setLayout( new FlowLayout() ). } // Lớp nội lắng nghe sự kiện private class CheckBoxHandler implements ItemListener { private int valBold = Font. container.getSource() == bold ) 116 . 100 ). } // execute application public static void main( String args[] ) { CheckBoxTest application = new CheckBoxTest(). private JCheckBox bold. bold.addItemListener( handler ). italic.// Java extension packages import javax. container. // Đặt ô nhập và font chữ field = new JTextField( "Theo dõi font chữ thay đổi". // Đăng ký đối tượng lắng nghe CheckBoxHandler handler = new CheckBoxHandler(). italic = new JCheckBox( "Italic" ).

ta có phương thức sau: public CheckboxGroup(). radioGroup.SELECTED ) valBold = Font. Với một nhóm các nút ta có thể lấy ra đối tượng hiện tại đang được chọn bằng cách gọi phương thức getSelectedCheckbox(). }}} III.addItemListener( handler ).add( italicButton ). else valItalic = Font. radioGroup. Về bắt các sự kiện cũng tương tự ô đánh dấu. valBold + valItalic. Cách sử dụng nút chọn: Ta tạo một đối tượng giao tiếp ItemListener để lắng nghe tình huống. italicButton.addItemListener( handler ). 14 ) ). // Đặt lại font chữ của ô text field.add( boldButton ).if ( event.setFont(new Font( "Serif".getSource() == italic ) if ( event. // Nhóm các ô lại radioGroup = new ButtonGroup().PLAIN.SELECTED ) valItalic = Font.getStateChange() == ItemEvent. Phương thức getItemSelectable sẽ trả về đối tượng nơi mà tình huống phát sinh: public ItemSelectable getItemSelectable(). Phương thức getItem của đối tượng ItemEvent sẽ cho ta biết giá trị nút chọn: public Object getItem().add( plainButton ). else valBold = Font. radioGroup. boldButton. Đặt lựa chọn ta dùng: setSelectedCheckbox().ITALIC.BOLD.addItemListener( handler ).getStateChange() = = ItemEvent. radioGroup.4 Nút chọn (radio button) Tạo nút chọn: Đây là trường hợp đặc biệt của ô đánh dấu.add( boldItalicButton ). boldItalicButton. Sau đây là ví dụ về sử dụng ô chọn: // Đăng ký đối tượng lắng nghe cho mỗi ô chọn radio RadioButtonHandler handler = new RadioButtonHandler(). plainButton. Ta tạo ra ô đánh dấu và đặt nó vào một nhóm. // Chọn ô chứ nghiêng if ( event.PLAIN. 117 .addItemListener( handler ).

addItemListener( new ItemListener() { // bắt sự kiện public void itemStateChanged( ItemEvent event ) { // liệu có phần tử được chọn if ( event.event.add( imagesComboBox ). // đặt một JLabel hiển thi ImageIcons tương ứng label = new JLabel( icons[ 0 ] ). // Thiết lập GUI public ComboBoxTest() { super( "Testing JComboBox" ).*.*. import java.setMaximumRowCount( 3 ). container.III.setIcon( icons[imagesComboBox. // Java core packages import java. private String names[] = { "bug1. imagesComboBox. Đây là một danh sách xổ xuống.getSelectedIndex() ] ).gif" }. "bug2. // khởi tạo combo imagesComboBox = new JComboBox( names ).*. JComboBox cũng phát sinh sự kiện ItemEvent giống như JRadioButton và JCheckBox. "buganim.gif". container.SELECTED ) label.swing. new ImageIcon(names[2]).5 Hộp thoại Combo Java hỗ trợ hộp thoại Combo thông qua đối tượng của class JComboBox.setLayout( new FlowLayout() ). // Java extension packages import javax. 118 .gif".awt.awt. "travelbug. new ImageIcon(names[3])}.gif". private JLabel label. public class ComboBoxTest extends JFrame { private JComboBox imagesComboBox. imagesComboBox. } } ). private Icon icons[] = { new ImageIcon(names[0]). // Đặt layout Container container = getContentPane().getStateChange() == ItemEvent. new ImageIcon(names[1]). Chương trình sau đây minh họa việc sử dụng JComboBox với các phần tử là các ảnh GIF. đưa ra một danh sách các mục và ta chỉ được chọn 1 mục trong đó.

replaceItem("Xanh". 4). vd: List list = new List(). boolean multiMode) Sử dụng danh sách chọn: Đưa từng phần vào danh sách bằng lệnh add(String item). setVisible( true ). setSize( 350. int index). }} III. 119 . Thay thế một phần tử ở vị trí pos bằng phần tử mới: replaceItem(String newItem.6 Danh sách (Lists) Lớp List cho phép ta tạo một danh sách các phần tử cho ta lựa chọn Tạo một danh sách: Phương thức khởi dựng mặc định: public List(). Để chọn một phần tử mà ta biết vị trí: select(int index) Nếu phần tử đang ở trạng thái chọn chuyển sang trạng thái bình thường: deselect(int index) Trạng thái của một phần tử: isSelected(int index) Chuyển chế độ đơn chọn sang đa chọn: setMultiplesSelections(boolean bl) Cho biết một danh sách là đơn chọn hay đa chọn: boolean isMultipleMode().setDefaultCloseOperation( JFrame. int pos) vd: list.add("Mau do").container.EXIT_ON_CLOSE ). aplication. hoặc để chỉ định bao nhiêu phần tử sẽ được hiển thị cùng một lúc trong danh sách: public List(int rows) hoặc tạo một danh sách cho phép lựa chọn nhiều phần tử cùng một lúc: public List(int rows. index là vị trí phần tử mà ta muốn chèn. Loại bỏ một phần tử trong danh sách ta dùng phương thức remove(int pos). Trả về vị trí của phần tử được chọn.add( label ). Sử dụng đối số ItemEvent trong phương thức itemStateChange để biết được chỉ số của phần tử đang thay đổi trạng thái. Chèn một phần tử vào danh sách bằng phương thức add(String item. Chọn nhiều thì dùng: String[] getSelectedItem(). Nếu được chọn nhiều thì dùng: int[] getSelectedIndex() Lấy ra phần tử được chọn: getSelectedItem().vd: list. Sử dụng đối tượng danh sách: Cài đặt giao tiếp ItemListener để tạo đối tượng biết lắng nghe sự thay đổi trạng thái của các phần tử trong danh sách. nếu không có phần tử nào được chọn thì giá trị sẽ là 1: getSelectedIndex(). 100 ). Loại bỏ hết danh sách: removeAll(). } // hàm main public static void main( String args[] ) { ComboBoxTest application = new ComboBoxTest().

"Green".*.Để xử lý được tình huống nhấp đôi chuột.yellow }. colorList. container.*.setLayout( new FlowLayout() ). "Orange". private Container container.pink. // lấy layout container = getContentPane(). "Light Gray". "Pink". Color. setVisible( true ).lightGray. "Cyan". // thêm một JScrollPane chứa danh sách container. "Magenta". "Yellow" }. Color. // Java extension packages import javax. Color. } } ). Color. 120 . Color.swing.event. "Gray".blue. Phương thức getActionCommand() trong ActionEvent sẽ trả về tên của phần tử bị nhấp. Color.magenta.white.red.SINGLE_SELECTION ). "Red".setVisibleRowCount( 5 ). private Color colors[] = { Color.getSelectedIndex() ] ).orange.black. 150 ).*. "White".add( new JScrollPane( colorList ) ). Color. public class ListTest extends JFrame { private JList colorList.addListSelectionListener( new ListSelectionListener() { public void valueChanged( ListSelectionEvent event ) { container.setSelectionMode(ListSelectionModel. Color. private String colorNames[] = { "Black". // đặt lắng nghe sự kiện colorList.setBackground( colors[ colorList. "Dark Gray". "Blue". // Java core packages import java.cyan.gray. Color. Color. Color. import javax. // Tạo danh sách colorList = new JList( colorNames ). // Không cho chọn nhiều colorList.green. Color. // Thiết lập GUI public ListTest() { super( "List Test" ). setSize( 350.darkGray.swing. ta cài đặt giao tiếp ActionListener và gắn nó vào danh sách.awt.

 Tạo một ô văn bản với nội dung là một chuỗi cho trước: public TextFiled(String initText). kích thước bất kỳ: public TextArea(). Cho phép soạn thảo được: public void setEditable(boolean canEdited).setDefaultCloseOperation( JFrame. ví dụ: myTextField.  Tạo một ô văn bản hiển thị tối thiểu numCols ký tự: public TextField(int numCols). Lấy nội dung văn bản trong các đối tượng: public String getText().} // hàm main public static void main( String args[] ) { ListTest application = new ListTest(). int numCols). //mã mKhẩu Xác định xem ký tự làm ký tự hiển thị: public char getEchoChar(). Đặc điểm riêng của TextField: Đặt ký tự hiển thị cho ký tự nhập vào: public void setEchoChar(Char ch). int cols). Lấy nội dung văn bản được đánh dấu: public String getSelectedText(). application. Xác định đối tượng đang ở trang thái nào: public boolean isEditable(). Để xác định xem vị trí đánh dấu khối văn bản bắt đầu và kết thúc ở đâu: public int getSelectionStart().7 Ô văn bản (text field) và vùng văn bản (text areas) Tạo ô văn bản:  Khởi tạo một ô văn bản không xác định kích thước: public TextField(). }} III. Xác định chiều dài của ô văn bản theo ký tự: public int getColums(). int cols) Đặc điểm chung của các thành phần văn bản: Hai lớp này được dẫn xuất từ lớp TextComponent Muốn đưa nội dung văn bản vào các đối tượng này ta sử dụng phương thức setText: public void setText(String newText).  Tạo một vùng văn bản với số dòng số cột và nội dung cho trước: public TextArea(String st.  Tạo vùng văn bản:  Tạo vùng văn bản rỗng.  Tạo ô văn bản kết hợp: public TextField(String initText. canEdited = false: chỉ đọc. //cuối Đánh dấu toàn bộ văn bản: public void selectAll().  Tạo một vùng văn bản với số cột và số dòng định trước: public TextArea(int rows.EXIT_ON_CLOSE ). sử được.  Tạo một vùng văn bản với nội dung cho trước: public TextArea(String initiaText). //đầu public int getSelectionEnd().setEchoChar('*'). 121 . int rows. canEdited = true: thêm. Đặc điểm riêng của đối tượng TextArea: Đưa thêm một dòng văn bản vào đối tượng: public void appendText(String newText).

container.setEditable( false ).add( textField3 ).awt. container. container. setSize( 325. setVisible( true ). } // hàm main public static void main( String args[] ) 122 .add( textField1 ). // ô nhập không cho phép nhập. Xác định kích thước hiển thị: public int getRows(). textField3. Khi người dung nhấn Enter thì tình huống được gọi. Sử dụng đối tượng TextField và TextArea: Muốn lấy nội dung văn bản của đối tượng. // ô nhập với kích thước mặc định textField1 = new JTextField( 10 ).awt. import java. int pos). textField3. public int getColums().addActionListener( handler ).*.Chèn một chuỗi văn bản vào vị trí bất kỳ: public void insertText(String newText. import javax.event.addActionListener( handler ). // constructor của JFrame Container container = getContentPane().*. container.add( passwordField ). // ô nhập với văn bản có sẵn textField2 = new JTextField( "Enter text here" ).setLayout( new FlowLayout() ).swing. chỉ hiên thị thông tin textField3 = new JTextField( "Uneditable text field". textField2. private JPasswordField passwordField.add( textField2 ).*. textField3. 100 ). public class TextFieldTest extends JFrame { private JTextField textField1. // ô nhập password passwordField = new JPasswordField( "Hidden text" ). container. passwordField. import java. // Thiết lập giao diện GUI public TextFieldTest() { super( "Testing JTextField and JPasswordField" ).addActionListener( handler ). ta thiết lập ActionListener để gắn đối tượng xử lý tình huống vào văn bản TextField. textField2. textField1. // Đăng ký bộ lắng nghe sự kiện TextFieldHandler handler = new TextFieldHandler().addActionListener( handler ). 20 ).

// khi người dùng ấn enter if ( event. // user pressed Enter in JTextField passwordField else if ( event.getActionCommand().getSource() == textField3 ) string = "textField3: " + event.setDefaultCloseOperation( JFrame.getPassword() ). vị trí hiện hành sẽ thay đổi. 123 .{ TextFieldTest application = new TextFieldTest(). Khi người dùng kích chuột vào mũi tên ở hai đầu thì tình huống line nảy sinh. // user pressed Enter in JTextField textField3 else if ( event. } JOptionPane.getActionCommand(). // Hiên thị cửa sổ thông báo } } } III.showMessageDialog( null. string ). // user pressed Enter in JTextField textField2 else if ( event.getSource() == textField2 ) string = "textField2: " + event. Tình huống page nảy sinh khi người dùng kích chuột vào khoảng giữa thanh trượt.getActionCommand().EXIT_ON_CLOSE ).8 Thanh trượt (Scrollbar) Ta có thể đặt thanh trượt các giá trị giới hạn tối thiểu (min) và tối đa (max) cùng với vị trí hiện tại trên thanh trượt. string = "passwordField: " + new String( passwordField. } // Lớp nội cho bộ lắng nghe sự kiện private class TextFieldHandler implements ActionListener { // phương thức xử lý sự kiện public void actionPerformed( ActionEvent event ) { String string = "". thanh trượt sẽ tự động cộng thêm hay trừ đi một đơn vị. Tạo thanh trượt: Phương thức khởi tạo: public Scrollbar(). application.getSource(). Tình huống absolute nảy sinh khi người dùng nắm vào vị trí hiện hành của thanh trượt và kéo nó đi.getSource() == passwordField ) { JPasswordField pwd = ( JPasswordField ) event. Đối tượng Scrollbar chỉ chịu trách nhiệm di chuyển và cung cấp cho ta giá trị thay đổi.getSource() == textField1 ) string = "textField1: " + event.

Có 3 trạng thái: line. Tạo thanh trượt có đầy đủ thông số ban đầu: public Scrollbar(int orienttation. 124 . IV.setValues(75. Ta đặt cho nó một phím tắt.VERTICAL . Muốn biết hiện thời đơn vị thay đổi là bao nhiêu: public int getBlockIncrement(). ví dụ: myScrollbar. //vị trí khởi đầu int pageUnit. Đặt lại vị trí hiện hành cho thanh trượt: public void setValue(int newPos).VERTICAL và Scrollbar. vị trí thanh trượt tăng 1 đơn vị. khi người dùng chọn vào đó sẽ sổ xuống danh sách các mục chọn khác. int pos. page và absolute. frm. //bước nhảy int minValue. public int getMinimum(). ta lấy vị trí thanh trượt bằng hàm getValue(). Ta sử dụng hàm getAdjustmentType() để xác định xem tình huống nào đang xảy ra. vị trí hiện hành tăng 1 đv. Sử dụng thanh trượt: Ta nhờ đối tượng xử lý tình huống xử lý: public void adjustmentValueChanged(AdjustmentEvent evt). //giá trị min int maxValue).UNIT_DECREMENT: tình huống line xảy ra.Track: tình huống absolute xảy ra. ta cần thêm vào đó các JMenu là các mục trên thanh Menu. 10.cho đứng.BLOCK_INCREMENT: tình huống page xảy ra. Scrollbar. 500). ví dụ là „F‟ để khi ấn Alt + F thì JMenu này được kích hoạt: file. AdjustmentEvent. Lấy giá trị lớn nhất và nhỏ nhất: public int getMaximum(). int maximum). AdjustmentEvent.HORIZONTAL.setMnemonic('F'). Thành phần Menu Lớp JMenuBar cài đặt thanh thực đơn và trong đó có thể chứa các thực đơn pull-down.setJMenuBar(menuBar).UNIT_INCREMENT: tình huống line xảy ra. int minimum. Các JMenuBar được tạo ra để gắn vào một của sổ JFrame bằng một lệnh gọi: JMenuBar menuBar = new JMenuBar(). // MenuBar này chưa có phần tử nào Sau khi có MenuBar. Muốn biết thanh trượt đứng hay ngang: public int getOrientation() trả về giá trị là một trong hai hằng số Scrollbar. Cho ta vị trí hiện hành: public int getValue(). //giá trị max Một số phương thức hay dùng: Thay đổi giá trị tăng giảm (mặc định là 1): public void setUnitIncrement(int increment). AdjustmentEvent. Muốn biết hiện thời tăng giảm bao nhiêu: public int getUnitIncrement() Chỉ định con số khi tình huống page xảy ra: pubic void setBlockIncrement(int b). Thiết lập lại các thông số cho thanh trượt: public void setValues(int position. int pageUnit. orienttation nhận giá trị Scrollbat. JFrame frm = new JFrame(“Day la mot Frame”).Tạo thanh trượt đứng hay ngang ta dùng: public Scrollbar(int orienttation). vị trí thanh trượt giảm 1 đơn vị.HORIZONTAL cho nằm ngang. 0. JMenu file = new JMenu(“File”). AdjustmentEvent.

một dấu kiểm tra (check mark) sẽ hiện bên trái mục chọn: Mục đánh dấu: CheckboxMenuItem Autosave = new CheckboxMenuItem("Auto save").add("to preview"). ta dùng: Autosave. JMenuItem open = new JMenuItem(“Open”.add(Autosave). Xác định xem mục chọn Autosave đang ở trạng thái nào.*. Lớp JPopUpMenu biểu diễn cho thực đơn pop-up.disable(). Khi sử dụng. Đặt trạng thái cho mỗi mục chọn sử dụng enable() hoặc disable(): Vi dụ: openItem. class MenuBarSample extends JFrame { //Khai bao mot hop thoai JOptionPane op = new JOptionPane(). ta tạo một menu bình thường rồi đưa vào menu đã có. // Khai bao mot thuc don pop-up JPopupMenu jp.addSeparator(). import java. //được chọn openItem. Tạo một mục chọn có khả năng đánh dấu (check Item). Tạo thanh trình đơn: JMenuBar myMenubar = new JMenuBar().add(printItem). Nếu ta cần biểu diễn các dòng kẻ ngang để phân tách các mục chọn thì ta có thể gọi phương thức addSeparator() của một đối tượng JMenu: file.addSeparator().event. Ở đây ta đã gọi một constructor với một tham số là nhãn của mục chọn. //mờ mục chọn Ta có thể dùng đường phân cách để tách các mục chọn: FileMenu. Những thực đơn này có thể xuất hiện bất cứ vị trí nào trong cửa sổ hiện tại. Ví dụ: //tạo mục chọn có menu con JMenu printItem = new JMenu("Print").enable(). để mục chọn tương tác và nhận được sự kiện ta cần cài đặt giao diện ActionListener và gắn vào từng mục chọn. //đưa mục chọn có menu con vào menu chính FileMenu.add("Print preview"). một tham số là ký tự phím tắt.swing.getState(). public MenuBarSample() 125 . import javax.awt.*. Sau đó ta add vào JMenu: file. import java. FileMenu.‟O‟). Bây gời là lúc ta cài đặt các mục chọn trong một JMenu. Lớp JCheckBoxMenuItem chứa các mục được chọn để kiểm tra trong các mục thực đơn. Tạo mục chọn có chứa menu con khác.Sau đó thì thêm nó vào JMenuBar: menuBar.add(open). //tạo các mục chọn cho menu con printItem. printItem. Sau đây là một ví dụ xây dựng một JFrame với thanh menu và các mục chọn trong đó có cài đặt xử lý các sự kiện.awt.add(file). Java dùng lớp JMenuItem định nghĩa từng mục của thực đơn.*.

getContentPane() de lay Container cua Frame op. } } ). // Khai bao mot muc chon kieu checkbox 126 .showMessageDialog(getContentPane().add(fileOpen). // Dat ky tu kich hoat tat cung Alt menuFile.getItem(1)."Ban vua chon Open").setMnemonic('F'). // Khai bao mot muc chon voi phim tat O JMenuItem fileOpen = new JMenuItem("Open".add("Save").addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { op. // Dat kieu trinh bay pane.menuBar.add(new JMenuItem("New".getItem(3).'N')). // Them dong ngan cach menuFile. // Xu ly su kien chon Save menuFile.{ // Lay ve doi tuong chua cua Frame hien tai Container pane = this.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent event) { // Hien thi thong bao.showMessageDialog(getContentPane(). // Xu ly su kien chon New menuFile. // Khai bao muc File trong thanh menu JMenu menuFile= new JMenu("File").showMessageDialog(getContentPane(). // Them mot muc chon co ten Save menuFile.getContentPane(). // Them muc chon vao muc File menuFile.setLayout(new FlowLayout(FlowLayout.'O'). } } ). } } ).addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { op.add(menuFile)."Ban vua chon New"). // Them mot muc chon khac voi phim tat N menuFile. // Khai bao mot thanh menu JMenuBar menuBar= new JMenuBar()."Ban vua chon Save").LEADING)). // Xu ly su kien chon muc Open fileOpen.addSeparator().

showMessageDialog(getContentPane().add(chk). } } ).BUTTON3_MASK) jp.addMouseListener( new MouseAdapter() { public void mouseClicked(MouseEvent e) { if( (e. jp. jp.isSelected()) //Neu duoc chon op.addSeparator().add("Create").add("New Document"). } } ).JCheckBoxMenuItem chk = new JCheckBoxMenuItem("is editting").getX(). m.e. this."Ban vua bo chon is editting"). // Them phan xu ly su kien chon hay khong chon cho no chk. // Cap phat bo nho cho popup menu jp = new JPopupMenu("Popup"). m."Ban vua chon is editting"). jp.400).getModifiers() & InputEvent.showMessageDialog(getContentPane().getSource().setJMenuBar(menuBar).addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { // Lay ve doi tuong nguon su kien va ep kieu JCheckBoxMenuItem ck = (JCheckBoxMenuItem)e. else // Neu khong duoc chon op.e. } } V. if (ck.BUTTON3_MASK)== InputEvent.setVisible(true). Bộ quản lý cách trình bày (Layout Manager) Dùng để sắp xếp chỗ và định vị cho các đối tượng GUI.show(getContentPane(). } public static void main(String[] argvs) { MenuBarSample m = new MenuBarSample(). // Them muc chon checkbox vao menu File menuFile. // Dat thanh Menu cho Frame la doi tuong menuBar this.getY()). 127 .setSize(300.

 GridBadLayout: các đối tượng trong khung chứa cũng được đưa vào các ô của một khung lưới vô hình.LEFT. có 5 kiểu: "North".  CardLayout: Các đối tượng được đặt vừa vặn với khung chứa và nằm chồng lên nhau như các lá bài. ta phải định hình trước đối tượng đó đặt ở đâu: myWindow. South.2 Cách trình bày GridLayout: Phương thức khởi tạo: public GridLayout(int Rows. hoặc chỉ định luôn cách căn lề bằng phương thức khởi tạo: public FlowLayout(int align). Các đối tượng giữ nguyên kích thước. Xác định khoảng cách giữa các đối tượng quản lý: public GridLayout(int Rows. ta dùng hộp thoại thông báo. Ví dụ: myWindow.setLayout(objectsLayout). int vgap). Tạo bộ quản lý kiểu BorderLayout: public BorderLayout().CENTER hoặc chỉ ra khoảng các giữa các đối tượng trên cùng một hàng: public FlowLayout(int align. East. "Center". theo các cạnh của khung. Nort và Center. "West". "South". int hgap. Ví dụ: GridLayout layout = new GridLayout(3. 2). V. new Button("on Top")). "East".1 Cách trình bày FlowLayout: Tạo đối tượng FlowLayout. kích thước các đối tượng không nhất thiết phải vừa một ô.3 Cách trình bày BorderLayout Đối tượng được đặt theo đường viền khung chứa.RIGHT. Muốn áp dụng ta tạo ra đối tượng trên rồi chuyển nó cho khung chứa. Lớp JOptionPane có 4 phương thức tĩnh sau: Tên phương thức Giá trị trả về Ý nghĩa 128 .Có 5 cách trình bày:  FlowLayout: sắp xếp các đối tượng từ trái qua phải và từ trên xuống dưới. ta sử dụng phương thức: public FlowLayout(). FlowLayout. hay có thể viết gọn hơn: myWindow. Khi đưa đối tượng vào khung chứa. V.  BorderLayout: Các đối tượng được đặt theo đường viền của khung chứa theo các cạnh West. align là FlowLayout. Java hỗ trợ lớp JOptionPane để ta thực hiện công việc này. các đối tượng sẽ đặt vừa kích thước với các ô đó. FlowLayout.setLayout(new BorderLayout()). int Cols. myWindow.setLayout(new FlowLayout()).  GridLayout: tạo một khung lưới vô hình với các ô bằng nhau. Các hộp thoại VI. int hgap.1 Hộp thoại thông báo Khi cần đưa ra thông báo hay hỏi người dùng một vấn đề gì đó và nhận về câu trả lời. int Cols). int vgap). Ví du: FlowLayout objectsLayout = new FlowLayout(). VI. V.add("North".

WARNING_MESSAGE). có thể đặt: chooser.Để cho phép chọn nhiều file: chooser. Để dùng được bộ lọc file ta phải thiết kế một lớp kế thừa từ lớp javax.")).endsWith(". .swing.2 Hộp thoại chọn File Khi viết ứng dụng ta gặp các tình huống mở file để đọc hoặc ghi. JOptionPane. Hai phương thức quan trọng là: .setMultiSelectionEnabled(true).toLowerCase(). 5. JOptionPane.OK_OPTION) .showMessageDialog Không có showConfirmDialog Số int showOptionDialog showInputDialog Số int Chuỗi Hiển thị một thông báo và đợi ấn OK Hiển thị thông báo và đợi xác nhận Ok hay Cancel Hiển thị thông báo và nhận về trả lời từ một danh sách chọn Hiển thị thông báo và nhận về một dòng do user nhập vào icon hiển thị phụ thuộc vào loại thông báo: ERROR_MESSAGE : Thông báo lỗi INFORMATION_MESSAGE : Thông tin WARNING_MESSAGE :Cảnh báo QUESTION_MESSAGE: Hỏi PLAIN_MESSAGE: Giải thích Các hằng số này được truy cập qua JOptionPane. VI.filechooser. 4.Đặt thư mục cho hộp thoại: chooser.showConfirmDialog(parent.showOpenDialog: Để hiện thị hộp thoại chọn mở file . 2. Ví dụ bộ lọc file Gif: public class GifFilter extends FileFilter { public boolean accept(File f) { return f.setSelectedFile(new File(filename)).FileFilter. 3.Nếu định chọn trước một file.OK_CANCEL_OPTION. "Message". if (selection == JOptionPane.showSaveDialog: Để hiện thị hộp thoại chọn ghi file Sau đây là các bước để làm việc với hộp thoại chọn file: 1.gif") || f.isDirectory(). Swing hỗ trợ một lớp JFileChooser để ta thực hiện công việc này.getName(). dùng bộ lọc file. Ví dụ: int selection = JOptionPane. .Tạo một đối tượng JFileChooser: JFileChooser chooser = new JFileChooser().setCurrentDirectory(new File(". } public String getDescription() { 129 . "Title".Nếu muốn giới hạn kiểu file.

7. Hãy thiết kế một giao diện có nội dung như sau: 130 .DIRECTORIES_ONLY hoặc JFileChooser. dialog = JColorChooser. Khi làm việc với hộp thoại chọn màu ta cần cung câp: . nếu muốn cho phép chọn thư mục dùng phương thức: setFileSelectionMode() với các tham số: JFileChooser. JFileChooser.return "GIF Image".chế độ hộp thoại modal hay modeless.Mặc định thì chỉ cho phép chọn file. false /* not modal */."Background Color". VI.Hiển thị hộp thoại bằng lệnh gọi: int result = chooser.bộ lắng nghe cho nút bấm Ok và Cancel.title.getColor()). Bài tập 1.Lấy vè file hoặc các file được chọn dùng: getSelectedFile() hoặc getSelectedFiles().showOpenDialog(parent). } }.setFileFilter(new GifFilter()). Cú pháp sử dụng như sau: Color selectedColor = JColorChooser.APPROVE_OPTION.CANCEL_OPTION.một đối tượng chọn màu . Các giá trị trả về là JFileChooser. } } Sau đó gán cho hộp thoại: chooser. or JFileChooser. . initialColor). String filename = chooser. .ERROR_OPTION 8.parent: một companent cha.title: Tiêu đề hộp thoại. chooser. new ActionListener() // Lắng nghe cho OK { public void actionPerformed(ActionEvent event) { setBackground(chooser.3 Hộp thoại chọn màu Swing hỗ trợ lớp JColorChooser để người dùng chọn màu. null /* Không có lắng nghe cho Cancel */). hoặc int result = chooser.getSelectedFile(). chooser = new JColorChooser().createDialog(parent. 6. Neus chỉ muốn lấy tên file thì ta dùng phương thức getPath().getPath(). .showSaveDialog(parent).FILES_AND_DIRECTORIES.showDialog(parent.

Hãy lập trình để xử lý sự kiện click chuột phải lên nền của sổ sẽ hiện một menu Popup. Viết chương trình giải phương trình bậc 2 với giao diện GUI. Trường hợp không có nghiệm sẽ hiển thị một hộp thoại thông báo “chương trình vô nghiệm”. Yêu cầu chương trình có các ô nhập các hệ số a. b.2. 131 . c và cho phép xem kết quả. 3.

2.Đề tài 11. Khả năng này của Java gọi là tính đa luồng.…. I. Phương thức này trả về true nếu ngắt thành công. các luồng khác có thể phát sinh từ luồng chính này. nó trả về điều khiển cho chương trình gọi nó.  Phương thức joint đợi (wait) một phản hổi của một thông điệp được gửi đi trước khi thực hiện thread. Khái niệm thread I. chương trình gọi nó và thread được thực hiện một cách đồng thời. Phương thức isInterrupted() dùng để kiểm tra xem thread có bị ngắt hay không. Các công việc của một thread được đặt trong phương thức run(). Sau khi start() thực hiện xong.  Phương thức isAlive() trả về true nếu start() đã được gọi và phương thức run() vẫn đang thực hiện. Trong mỗi chương trình Java. độ ưu tiên và nhóm của thread. Phương thức toString() trả về tên phương thức. Thread_2. Threading Java là ngôn ngữ thông dụng duy nhất hỗ trợ cho lập trình viên các giải pháp lập trình song song.  Phương thức static currentThread() trả về tham chiếu tới thread hiện hành đang thực hiện.  Phương thức tĩnh sleep của Thread được gọi với một tham số xác định rằng một thread đang chạy sẽ dừng lại trong bao lâu theo đơn vị phần nghìn giây.3 Các bước để tạo một thread Sau đây là các bước đơn giản để thực hiện một nhiệm vụ trong một thread riêng: 132 . Lập trình viên xác định số lượng các thread được chạy trong chương trình và chúng được thực hiện song song với nhau ở những giai đoạn nào. Người lập trình bắt đầu một thread bằng các gọi phương thức start(). phương thức start() sau đó sẽ gọi run().lang có một số constructor: Public Thread (<tên thread>) Public thread(): Khi này thread sẽ có tên là Thread_1.  Phương thức start() sẽ ném ra một ng oại lệ IllegalThreadStateException nếu thread cần bắt đầu đã bắt đầu rồi. Các câu lệnh trong hàm main() nếu không được đưa vào một luồng riêng thì sẽ được thực hiện tuần tự. có một luồng chính được bắt đầu bằng việc gọi hàm main(). I. Lớp Thread Lớp Thread trong gói java.  Phương thức setName() đặt tên cho một thread. Phương thức này có thể được khai báo chồng trong lớp khai báo kế thừa Thread hoặc khai báo cài đặt giao diện Runable. getName() lấy tên một thread. Do đó.1 Khái niệm: Thread – luồng chỉ một đơn vị chương trình có thể tách khỏi các phần khác của chương trình để thực hiện song song với các phần khác ở từng khoảng thời gian hoặc trong toàn bộ quá trình nó thực hiện. Trong khi một thread “sleep”. I.  Phương thức interrupt() được gọi để để ngắt một thread. nó sẽ không tiêu tốn tài nguyên CPU và thread khác có thể chạy.

Sau đây là sơ đồ trạng thái của một thread. tread sẽ thoát khỏi trạng thái sleep và chuyển sang trạng thái ready. Trạng thái ready: Khi phương thức start() được gọi.1.  Trạng thái dead: Khi một Thread ngưng hoặc hoàn thành nhiệm vụ của nó.3 và 4 để thực hiện thread. Trạng thái born: Khi thread chưa gọi start(). một thread running cũng có thể bị chặn (blocked) trong các thao tác vào ra. Khai báo một lớp có cài đặt giao diện Runable với phương thức run() được định nghĩa: class MyRunnable implements Runnable { public void run() { // code thực hiện } } 2. Nếu đang ở trạng thái sleep mà gọi phương thức interrupt(). 3.start(). Gọi phương thức start() t. Một thread cũng có thể được tạo ra bằng cách xây dựng một lớp con của lớp Thread: class MyThread extends Thread { public void run() { // code của thread } } Sau đó ta cũng làm theo các bước 2. Tạo một đối tượng của lớp Runnable r = new MyRunnable(). Ngoài ra. Lúc này nó cũng không sử dụng tài nguyên CPU. 4.    133 .  Trạng thái sleep: Khi Thread gọi phương thức sleep. Các trạng thái của thread. Tạo một đối tượng Thread từ đối tượng Runable trên: Thread t = new Thread(r). Trạng thái running: Một Thread ở trạng thái ready có quyền ưu tiên cao nhất sẽ được chuyển sang trạng thái này. II.

Trình từ thực hiện của các thread theo độ ưu tiên của nó được minh họa như sau: 134 .1 Độ ưu tiên của thread Mỗi Thread có một độ ưu tiên.Khi một thread đang chạy gọi phương thức wait(). Mặc định thì thread thừa kế độ ưu tiên từ thread cha của nó. thread sẽ rơi vào một trạng thái wait để đợi một đối tượng mà nó đã gọi. Ta có thể tăng hoặc giảm độ ưu tiên của bất kỳ thread nào với phương thức setPriority() bằng một giá trị nằm giữa MIN_PRIORITY(1) và MAX_PRIORITY (10). III. Các thuộc tính của thread III.là thread đã gọi nó.

135 . với mỗi thread được tạo ra ta dùng constructor có khai báo nhóm thread: Thread t = new Thread(g.2 Nhóm thread Các thread có thể được đưa vào cùng một nhóm để có thể đồng thời làm việc với cả nhóm thread này. ngoại lệ này sẽ được gửi cho một bộ xử lý ngoại lệ không được kiểm soát. Để ngắt tất cả các thread trong nhóm g ta gọi: g. Để kiểm tra xem có thread nào trong nhóm g còn hoạt động không. threadName). Không có mệnh đề catch nào được thực hiện mà thay vào đó. ta dùng phương thức: g.3 Quản lý các ngoại lệ của thread Phương thức run() không thể ném ra một ngoại lệ được kiểm soát mà bị kết thúc bởi một ngoại lệ không kiểm soát được mỗi khi có lỗi. activeCount(). .Các thread có độ ưu tiên càng cao thì khả năng thực hiện càng cao.. III. ThreadGroup g = new ThreadGroup(groupName) Sau đó. Khai báo một nhóm Thread: String groupName = .interrupt(). . III. trước khi thread bị dead.

Điều khiển các thread Sau khi đã khởi động được một thread rồi.UncaughtExceptionHandler chỉ với 1 phương thức: void uncaughtException(Thread t. } catch (InterruptedException ie) { System. Lý do là thread bị dừng lại trong một khoảng thời gian lâu và trong khoảng thời gian đó nó không thể tự đánh thức nó được. 3. Throwable e).1 Interrupt một thread Khi sử dụng phương thức Thread. nếu Throwable là một đối tượng của TheadDead. các thread riêng lại phụ thuộc vào bộ xử lý của nhóm thread chứa nó. tên của thread và stack trace được gửi tới System. không có gì xảy ra.. } } // Phương thức main tạo và bắt đầu thread public static void main(String args[]) throws java. 2.getDefaultExceptionHandler trả về một bộ xử lý không phải là null thì bộ xử lý này được gọi. Mgoaif ra ta có thể cài bộ xử lý ngoại lệ mặc định cho tất cả các thread bằng cách gọi phương thức setDefaultUncaughtExceptionHandler của lớp Thread. IV. Tuy nhiên.io.sleep( 1000 * 60 * 60 * 8 ). ta có thể ngắt nó dùng phương thức interrupt()."). System. Khi này.out.println ("Thread đang ngủ.Nếu không..println ("Chỉ mới được hơn 5 phút thôi. try { // Ngủ trong 8 tiếng Thread.Ngược lại. phương thức uncaughtException sẽ làm các việc sau: 1. Từ phiên bản Java 1..err và đưa ra màn hình.out.Bộ xử lý này phải thuộc một lớp có cài đặt giao diện Thread. 4.Nếu là null.println ("Đó là một giấc ngủ trưa"). public class SleepyHead extends Thread { // Phương thức được chạy khi thread khởi động lần đầu public void run() { System. nếu phương thức Thread.err. IV. nếu một thread cần phải được đánh thức sớm hơn. 136 .sleep(int) thì chương trình thường phải bắt các ngoại lệ để xử lý. Nếu không cài bộ xử lý ngoại lệ cho một thread thì mặc định là null. ta có thể cài bộ xử lý ngoại lệ cho bất cứ thread nào bằng phương thức: setUncaughtExceptionHandler().IOException { // Tạo một thread Thread sleepy = new SleepyHead().5. vấn đề tiếp theo sẽ là điều khiển thread. Tuy nhiên.Nếu nhóm thread có cài đặt uncaughtException thì phương thức đó được gọi. Hãy đánh thức nó").

interrupt(). public class StopMe extends Thread { // Phương thức được thực hiện khi thread khởi động lần đầu public void run() { int count = 1.read().out.println ("Nhấn Enter để dừng đếm"). // Nhắc người dùng System.start().out.start(). // Dừng thread counter.println ("Thread đếm!"). } catch (InterruptedException ie) {} }} // phương thức main public static void main(String args[]) throws java. Ở đây.in.println ("Nhấn Enter để ngưng thread").hàm main. thread chính. Điều này yêu cầu thread điều khiển phải giữ một tham chiếu tới thread muốn dừng.// bắt đầu thread sleepy.read(). // Ngủ nửa giây try { Thread.print (count++ + " ").out..IOException { // Tạo và bắt đầu thread Thread counter = new StopMe(). System.in. sau đó gửi một thông điệp ngắt tới thread đang ngủ. }} Cách thực hiện ở đây là gửi một thông điệp từ một thread khác để đánh thức một thread đang ngủ. // Nhắc người dùng để dừng thread System.sleep(500).stop().io. for (. }} 137 .out. IV. Một thread (gọi là thread điều khiển) có thể gửi một thông điệp dừng tới một thread khác bằng việc gọi phương thức Thread. System. System.sẽ đợi cho người dùng ấn enter.) { // In ra biến count và tăng giá trị cho nó System.2 Dừng một thread Đôi khi ta muốn một thread dừng lại trước khi nhiệm vụ của nó hoàn thành. // Ngắt thread sleepy. counter.stop().

sleep(5000). Trong trường hợp này. // Nghỉ trong 5 giây try { Thread. System."). Ta không thể giải phóng thời gian CPU của bất kỳ thread nào mà chỉ đối với thread hiện thời.out. thread nên giải phóng thời gian hệ thống hơn là dùng sleep() để nghỉ trong thời gian dài.println ("Thread đã dừng").3 Tạm dừng và phục hồi một thread Các phương thức suspend() dùng để tạm dừng một thread trong khi resume() dùng để tiếp tục một thread đã bị suspend. // Nhắc user System. Một cách hiệu quả là gọi phương thức joint() để đợi một thread kết thúc công việc. nếu thường xuyên dùng phương thức này để kiểm tra sau đó dùng sleep() hoặc yield() thì hiệu quả sử dụng CPU sẽ rất thấp.out. Để làm điều này ta dùng phương thức static yield() của Thread để giải phóng thời gian CPU cho thread hiện thời.. IV.5 Đợi một thread kết thúc công việc Đôi khi ta cần đợi cho một thread kết thúc một công việc nào đó như gọi một phương thức hay đọc một thuộc tính thành phần. Tuy nhiên.…Ta dùng phương thức isAlive() để xác định thread còn chạy không. dying.4 Giải phóng thời gian cho CPU Khi một thread rơi vào trạng thái đợi một sự kiện xảy ra hoặc đi vào một vùng mã lệnh mà nếu giải phóng thời gian cho CPU sẽ nâng cao hiệu quả của hệ thống. IV.lang.InterruptedException { // Tạo thread Thread dying = new WaitForDeath().start()..join(). } catch (InterruptedException ie) {} } // phương thức main public static void main(String args[]) throws java.}} 138 . dying.println ("Đợi cho thread kết thúc").out. public class WaitForDeath extends Thread { // Phương thức run() public void run() { System. Tuy nhiên sử dụng các thread này rất hay gây ra tình trạng deadlock do thread bị suspend đang chiếm giữ một tài nguyên và không giải phóng trong khi nhiều thread khác có thể đang đợi sử dụng tài nguyên đó.IV.println ("thread chuẩn bị nghỉ..

double amount = maxAmount * Math. int to. accounts[from] -= amount.random(). Thread. chúng ta mô phỏng một ngân hàng có rất nhiều tài khoản khách hàng. các thread có thể cần phải truy cập đến cùng một đối tượng.out. from. 139 . System. giao dịch kết thúc ngay. trong một số tình huống chương trình trên có thể gây lỗi và in ra tổng số tiền khác nhau. Điều gì xảy ra nếu cả hai thread cùng truy cập đến đối tượng và làm thay đổi thuộc tính đối tượng.. toAccount. đó là khi có nhiều hơn một tài khoản cùng chuyển tiền đến một tài khoản khác. ta phải ấn Ctrl + C để dừng nó. public void transfer(int from. System. } Sau đây là đoạn code cho class transferRunnable: class TransferRunnable implements Runnable { . amount. tức là cùng thực hiện câu lệnh: account[to] += amount.. V.sleep((int) (DELAY * Math.currentThread()).1 Tình trạng “đua tranh” Trong phần tiếp theo.2f%n". public void run() { try { int toAccount = (int) (bank. to). Nếu account chuyển không đủ tiền.out. Ta có một class Bank với phương thức transfer để chuyển tiền.transfer(fromAccount. Mỗi tài khoản có một thread riêng.2f from %d to %d".random()). Tình trạng này gọi là “đua tranh”. double amount) { System.size() * Math. Đồng bộ thread Trong hầu hết các chương trình đa luồng.printf(" Số dư: %10. ta không biết được trong mỗi tài khoản còn bao nhiêu tiền nhưng tổng số tiền của tất cả các tài khoản là không đổi. accounts[to] += amount. Mỗi giao dịch thực hiện việc chuyển tiền từ account sang một account ngẫu nhiên khác. bank.V. Chương trình trên chạy và không bao giờ dừng lại.random())).out. Tuy nhiên.printf(" %10. getTotalBalance()). Chúng ta thử thiết kế một chương trình để chuyển tiền ngẫu nhiên giữa các tài khoản. Kết quả có thể là các thread bị ảnh hưởng lẫn nhau và không đạt được kết quả mong muốn. amount).print(Thread. } catch(InterruptedException e) {} } } Khi chương trình chạy.

hành vi chỉ chiếm một chu kỳ thực hiện lệnh của CPU). V. phép tính này lại không phải là atomic.2f%n". accounts[to] += amount. 140 .currentThread()). getTotalBalance()). trong một thời điểm sẽ chỉ có một thread được truy cập vào một đoạn mã lệnh nào đó. Điều này dẫn tới việc tổng số tiền bị thay đổi.lock(). Có nghĩa là. Cấu trúc đoạn lệnh căn bản để sử dụng cơ chế này là: myLock. int to.2 Khóa đối tượng Trong ví dụ trên. Tuy nhiên.print(Thread. khi đó mỗi thread sẽ thực hiện phép tính này một cách tuần tự mà không gây ảnh hưởng vì trong một thời điểm. Các phiên bản trước của Java sử dụng từ khóa synchronized. accounts[from] -= amount. // đảm bảo khóa được mở kể cả khi exception xảy ra } Đoạn lệnh này đảm bảo rằng chỉ có một thread tại một thời điểm có thể đi vào vùng được bảo vệ. công việc có thể phải làm là: 1. // đối tượng ReentrantLock try { //Đoạn lệnh cần bảo vệ } finally { myLock.Load giá trị account[to] vào thanh ghi 2. amount.out.2f from %d to %d". Từ phiên bản Java 5.0 có hỗ trợ hai cơ chế để bảo vệ một khối lệnh khỏi sự truy cập đồng thời. account[to] lúc này đã ghi đè giá trị do thread_2 cập nhật. Thread_1 thực hiện xong bước 1 và 2 thì bị ngắt.Cộng với account 3. phần tiền do thread_2 chuyển cho account[to] đã bị mất. thread_1 thức dậy và làm tiếp bước 3.unlock(). Java 5. System.out. CPU cũng chỉ phục vụ được cho một thread.Giả sử đây là một hành vi đơn vị (atomic.0 giới thiệu thêm lớp ReentrantLock cho mục đích này. to).Load kết quả ngược trả lại cho account[to] Giả sử có 2 thread là thread_1 và thread_2 cùng thực hiện đến dòng lệnh này.lock().out. sau đó thread_2 sẽ thực hiện câu lệnh trên với đầy đủ 3 bước tức là account[to] đã bị thay đổi giá trị. from. System. Bây giờ chúng ta sẽ khóa phương thức transfer() trong lớp Bank: public class Bank { public void transfer(int from. System. Tiếp theo. int amount) { bankLock. Khi một thread đầu tiên đã gọi lock thì không một thread nào sau đó có thể vượt qua lệnh lock(). nếu ta đảm bảo rằng phương thức transfer() được thực hiện thành công trước khi thread bị ngắt thì sẽ không có vấn đề gì xảy ra.printf(" Total Balance: %10. try { if (accounts[from] < amount) return.printf(" %10.

việc gọi transfer() để chuyển tiền chỉ được thực hiện khi số tiền của account gửi lớn hơn số tiền được gửi: if (bank. private Lock bankLock = new ReentrantLock(). chương trình rơi vào deadlock. Kết quả là thread này không bao giờ thoát khỏi tình trạng đợi. một thread có thể không thỏa mãn và nó không thực hiện việc chuyển tiền.. try { while (accounts[from] < amount) // Đợi cho đến khi tài khoản của nó có đủ tiền { // đợi . Đến đây.unlock(). to..lock(). Đây là tình huống mà ta phải sử dụng đối tượng điều kiện: class Bank { public Bank() 141 . // ReentrantLock là một lớp cài đặt giao diện lock. tức là công việc của nó là không hữu ích.. } // Chuyển tiền ..} finally { bankLock. Khi có điều kiện này.unlock().transfer(from. } V. int to. amount). } } .getBalance(from) >= amount) bank. nó cần hoàn thành công việc để có thể mở khóa cho các thread khác đi vào. ta có thể nghĩ ra một giải pháp là để thread đợi cho đến khi nó có đủ tiền để chuyển: public void transfer(int from. int amount) { bankLock.. chẳng hạn ở đây. Tuy nhiên ta thấy rằng vùng chứa lệnh chuyển tiền lại đang bị khóa bởi chính thread này nên các thread khác không thể chuyển tiền được. nếu trong đó công việc chính cần thực hiện bị giới hạn bởi một điều kiện nào đó. Tuy nhiên. } finally { bankLock.3 Đối tượng điều kiện Trong trường hợp thread đi vào vùng bảo vệ. } } Việc đợi ở đây sẽ kết thúc khi một thread khác chuyển tiền vào cho nó..

signalAll() để mở khóa cho các thread đang nằm đợi thỏa mãn điều kiện đủ tiền. Ở đây.newCondition(). Nó sẽ không thể mở khóa khi đang nằm trong vùng khóa cho đến khi một thread khác gọi signalAll().await(). Một khi thread đã thoát khỏi tình trạng đợi do await() gây ra. } } Chú ý là việc gọi signalAll() không phải là kích hoạt thread bị chặn ngay lập tức..vị trí gọi phương thức await() và kiểm tra lại điều kiện. int amount) { bankLock. Nếu không có thread nào gửi signalAll() thì thread đang đợi không có cách nào chạy tiếp được. public void transfer(int from.await().. Một phương thức await() nên được gọi trong một vòng lặp đợi: while (!(đủ tiền)) condition. sign() và await() trong vùng được bảo vệ. } Nếu phương thức transfer() kiểm tra và thấy rằng nó chưa đủ tiền để chuyển thì nó sẽ gọi: sufficientFunds. Một phương thức khác là sign() chỉ trao khóa cho một thread xác định thay vì tất cả.. int to. Vấn đề là khi nào thì gọi signalAll()? Nguyên tắc chung là khi một thread hoàn thành việc thay đổi trạng thái đối tượng thì nó nên gọi signalAll().await().{ . thread gọi await() không giả phóng tình trạng này cho một thread nào đó thì bản thân nó cũng bị chặn. sau khi cộng tiền vào cho tài khoản nhận và thì signalAll() sẽ được gọi..signalAll(). } . nó sẽ được chạy tiếp và cố gắng đi vào vùng khóa và bắt đầu từ vị trí mà nó chờ đợi trước đó . Một thread chỉ có thể gọi các phương thức signalAll(). // Chuyển tiền . Nó chỉ giải phóng tình trạng bị chặn của các thread khác cho đến khi nó kết thúc đoạn chương trình được bảo vệ. sufficientFunds = bankLock. try { while (accounts[from] < amount) sufficientFunds. private Condition sufficientFunds.Lúc này nó sẽ nằm chờ thread khác chuyển tiền. Một thread thực hiện xong việc chuyển tiền. 142 . chương trình sẽ bị treo.unlock(). nó nên gọi: sufficientFunds. Nếu tất cả các thread khác đều đang bị chặn. Có một sự khác nhau căn bản giữa một thread đang đợi để khóa (gọi phương thức lock() để đi vào vùng bảo vệ) và thread gọi phương thức await(). Việc gọi này sẽ giúp các thread cũng đang trong tình trạng chờ đợi này không bị chặn nữa và tiếp tục công việc với một giá trị tài khoản có thể đã bị thay đổi.. } finally { bankLock.lock(). sufficientFunds..

2. mỗi người chuyển cho một người khác trong số 9 người còn lại. anh ta thông báo cho tất cả các anh khác đang phải đợi trong ngân hàng là mình vừa chuyển tiền (gọi signalAll()) rồi đi ra ngoài. Mỗi thời điểm ngân hàng chỉ chuyển tiền cho một người. 9 người khác phải chờ ngoài cổng. người được gửi tiền sẽ được vào trong ngân hàng và giữ khóa cổng. sau đó những người đang đợi cũng quay ra cổng để đợi đến lượt vào. Sau khi chuyển xong. anh ta sẽ đợi ở trong ngân hàng (gọi await()) và ném khóa ra ngoài cổng cho tất cả 9 người kia. 143 . thực hiện việc chuyển tiền. Một trong số 9 người ngoài cổng sẽ được đi vào trong ngân hàng. Viết chương trình song song với 10 thread để cộng 10000 số tự nhiên liên tiếp từ 1 đến 10000. Bài tập 1. Viết một chương trình tạo một thread thực hiện việc giải một phương trình bậc 2 với các hệ số cho trước.Chúng ta có thể kết thúc phần này bằng một câu chuyện minh họa: Có 10 người cùng đến ngân hàng để chuyển tiền cho nhau. Nếu chẳng may người đang thực hiện chuyển số tiền lớn hơn anh ta có.

Phụ lục A. Một phần của khối try mà luôn được thực hiện Số thực 4 byte Một kiểu vòng lặp Không sử dụng Một lệnh điều khiển rẽ nhánh Chỉ ra các interfaces mà lớp sẽ cài đặt. hoặc một lớp hay phương thức không thể bị khai báo chống. Nhập một package Kiểm tra xem đối tượng có phải là biểu hiện của một lớp Số nguyên 4 byte Một kiểu trừu tượng với các phương thức được cài đặt tại các class 144 . Các từ khóa của Java Từ khóa abstract assert boolean break byte case catch char class const continue default do double else extends final finally float for goto if implements import instanceof int interface Ý nghĩa Một lớp hoặc phương thức trừu tượng Được sử dụng để định vị lỗi nội bộ chương trình Kiểu boolean Thoát khỏi lệnh switch hoặc các vòng lặp Số nguyên 1 byte Một lựa chon của switch Một mệnh đề của khối Try để bắt một ngoại lệ Kiểu ký tự Unicode Định nghĩa một class Không được sử dụng Tiếp tục tại vị trí cuối vòng lặp hiện thời Mệnh đề mặc định của switch Phần trên của vòng lặp do/while Kiểu số thực floating-number 8 byte Mệnh đề else của một lệnh if Xác định lớp cha của một lớp Một hằng số.

x từ 0. its children.. acos(double x) = arccos(x). double. not to objects of its class Use strict rules for floating-point computations the superclass object or constructor a selection statement synchronized a method or code block that is atomic to a thread this throw tHRows transient try void volatile while the implicit argument of a method. or a constructor of this class throws an exception the exceptions that a method can throw marks data that should not be persistent a block of code that traps exceptions denotes a method that returns no value ensures that a field is coherently accessed by multiple threads a loop Phụ lục B Một số hàm hay sử dụng a) Hàm toán học..math. lớp java. 2. 145 . asin(double x) = arcsin(x). atan(double x) = arctag(x). cos(double x) = cos(x). 5.. PI/2 4. 6. and other classes in the same package a feature that is accessible by methods of all classes returns from a method the 16-bit integer type a feature that is unique to its class. x từ -PI/2 .Math.0 . x là radian.lang. x có thể là các kiểu long. PI 3.. ceil(double x): làm cận trên hoặc cận dưới của số x. float.Từ khóa long Native new null package private protected public return short static strictfp super switch Ý nghĩa Sô nguyên 8 byte a method implemented by the host system Cấp phát vùng nhớ cho một đối tượng hoặc mảng mới Một tham chiếu null Một gói các lớp a feature that is accessible only by methods of this class a feature that is accessible only by methods of this class. {java. int.} 1. abs(number x): lấy |x|.*.

10. exp(double x) = ex. getSeconds(): trả về giá trị int chỉ giây đồng hồ trong phút.lang. tan(double x) = tg(x).. 12. Lớp Date khai báo java. getTime(): trả về là một số được tính theo giây đồng hồ. trong đó x. 4. Horstmann. 10. float. trong đó x. getDay(): trả về giá trị int là thứ trong tuần. 9. date lấy giá trị từ 1. 3. 8. 1. 11. 15. String(String s) : Khởi động một chuỗi bằng chuỗi s.0]. 1. log(double x) = Ln(x). 2. 0 = CN. random(): cho một số ngẫu nhiên trong [0.Date. 9.. 12. [2] Cay S. How to program”.getYear()+1900. Gary Cornell (2004). setYear(int year): thay đổi giá trị năm trong biến date. setMonth(int month): thay đổi giá trị tháng trong biến date. double.. fourth edition. 5. “Network Programming and Distributed Computing”. y}. getMinutes(): trả về giá trị int chỉ phút trong giờ. năm.. năm thực = date. getMonth(): trả về giá trị int là tháng trong năm (0. 3. b) Lớp String. tháng. 6. getHours(): trả về giá trị int chỉ giờ trong ngày. 13. y có thể là kiểu int. min(number x. 1 = mon. 6. Prentice Hall PTR [3] David Reilly. charAt(int i): trả về một ký tự thứ sau i. Addison Wesley 146 .11). . setDate(int date) đặt lại ngày trong biến. long. getYear(): trả về giá trị int là năm. float. 5.31 11. nếu x là kiểu double thì thành kiểu long. concat(String str): nối thêm chuỗi str vào sau.util. number y) = max{x. 2. toUpperCase(): chuyển đổi chuỗi thành chữ HOA. double y) = xy.11. setMinutes(int i): thay đổi giá trị phút trong biến date. volume 1.7.0. Khi sử dụng ta phải dùng Math. Tài liệu tham khảo [1] Deitel & Associates (2001). round(number x): làm tròn số x. khai báo java. length() : trả về giá trị int là độ dài một chuỗi. 4. max(number x. y}. ngày. 7. toLowerCase(): thay đổi chuỗi thành chữ thường. “Java. “Core Java™ 2”. double. 8. (year + 1900). 14. 14.2. 6 = Sat. sin(double x) = sin(x). long. giờ. Date(): cho thứ. Michael Reilly (2002). Lấy mốc là 1900. setHours(int hour): thay đổi giá trị giờ trong biến date...String. number y) = min{x. sqrt(double x) = 16. pow(double x. y có thể là kiểu int. month có giá trị 0. 13. String() : Khởi động một đối tượng chuỗi. 8. indexOf(int ch): trả về vị trí trước của ký tự ch đầu tiên tìm thấy. 1. nếu x là kiểu float thì thành kiểu int. getDate(): trả về giá trị của ngày trong tháng. setSeconds(int i): thay đổi giá trị giây trong biến date. 15.tên_hàm. 7.