Ngôn ngữ lập trình java (Bản đẹp)

pdf 649 trang ngocly 1630
Bạn đang xem 20 trang mẫu của tài liệu "Ngôn ngữ lập trình java (Bản đẹp)", để tải tài liệu gốc về máy bạn click vào nút DOWNLOAD ở trên

Tài liệu đính kèm:

  • pdfngon_ngu_lap_trinh_java_ban_dep.pdf

Nội dung text: Ngôn ngữ lập trình java (Bản đẹp)

  1. Chương 1 CÁ C KHÁ I NIÊṂ CƠ BẢ N BÀI 1. LÀM QUEN VỚ I JAVA I. Lic̣h sử java Java là môṭ ngôn ngữ lâp̣ triǹ h đươc̣ Sun Microsystems giới thiêụ vào tháng 6 năm 1995. Từ đó, nó đã trở thành môṭ công cu ̣ lâp̣ triǹ h của các lâp̣ triǹ h viên chuyên nghiêp̣ . Java đươc̣ xây dưṇ g
  2. trên nền tảng của C và C++. Do vâỵ nó sử duṇ g các cú pháp của C và các đăc̣ trưng hướng đối tươṇ g của C++. Ban đầu Java đươc̣ thiết kế để làm ngôn ngữ viết chương triǹ h cho các sả n phẩm điêṇ tử dân duṇ g như đầu video, tivi, điêṇ thoaị, máy nhắn tin . Tuy nhiên với sư ̣ mañ h mẽ của Java đã khiến nó nổi tiếng đến mức vươṭ ra ngoài sư ̣ tưởn g tươṇ g của các nhà thiết kế ra nó. Java khởi thuỷ tên là Oak-
  3. là cây sồi moc̣ ở phiá sau văn phòng của nhà thiết kế chiń h ông Jame Gosling, sau này ông thấy rằng đa ̃ c ó ngôn ngữ lâp̣ triǹ h tên Oak rồi, do vâỵ nhóm thiết kế quyết điṇ h đổi tên, “Java” là cái tên đươc̣ choṇ , Java là tên của môṭ quán cafe mà nhóm thiế t kế java hay đến đó uống. II. Java em là ai Java là ngôn ngữ lâp̣ triǹ h hướng đối tươṇ g, do vâỵ không
  4. thể dùng Java để viết môṭ chương triǹ h hướng chức năng. Java có thể giải quyết hầu hết các công viêc̣ mà các ngôn ngữ khác có thể làm đươc̣ . Java là ngôn ngữ vừa biên dic̣ h vừa thông dic̣ h. Đầu tiên ma ̃ nguồn đươc̣ biên dic̣ h bằng công cu ̣ JAVAC để chuyển thành daṇ g ByteCode. Sau đó đươc̣ thưc̣ thi trên từng loaị máy cu ̣ thể nhờ chương triǹ h
  5. thông dic̣ h JAVA. Muc̣ tiêu của các nhà thiết kế Java là cho phép người lâp̣ triǹ h viết chương triǹ h môṭ lần nhưng có thể chaỵ trên bất cứ phần cứng cu ̣ thể, thế nên khẩu hiêụ của các nhà thiết kế Java là “Write One, Run Any Where”. Ngày nay, Java đươc̣ sử duṇ g rôṇ g r ã i để viết chương trình c ha ỵ trên Internet. Nó là ngôn ngữ lâp̣ triǹ h hướng đối tươṇ g đôc̣ lâp̣ thiết bi, ̣ không phu ̣ thuôc̣ vào
  6. hê ̣ điều hành. Java không chỉ dùng để viết các ứng duṇ g chaỵ đơn lẻ hay trong ma ṇ g mà cò n để xây dưṇ g các triǹ h điều khiể n thiết bi ̣ cho điêṇ thoaị di đôṇ g, PDA, II. Môṭ số đăc̣ trưng củ a java 1.Đơn giả n Những người thiết kế mong muốn phát triển môṭ ngôn ngữ dễ hoc̣ và quen thuôc̣ với đa số người lâp̣ triǹ h. Java tưạ như C++, nhưng đa ̃ lươc̣ bỏ đi các
  7. đăc̣ trưng phức tap̣ , không cần thiết của C và C++ như: thao tác con trỏ, thao tác điṇ h nghiã chồn g toá n tử (operator overloading), Java không sử duṇ g lêṇ h “goto” cũng như file header (.h). Cấu trúc “struct” và “union” cũng đươc̣ loaị bỏ khỏi Java. Nên có người bảo Java là “C++ “, ngu ̣ ý bảo java là C++ nhưng đã bỏ đi những thứ phức tap̣ , không cần thiết. 2. Hướ ng đố i tươṇ g
  8. Có thể nói java là ngôn ngữ lâp̣ triǹ h hoàn toàn hướ ng đối tươṇ g, tất cảc trong java đều là sư ̣vâṭ, đâu đâu cũng là sư ̣vâṭ. 3. Đôc̣ lâp̣ vớ i hê ̣nền Muc̣ tiêu chiń h của các nhà thiết kế java là đôc̣ lâp̣ với hê ̣ nền hay còn goị là đôc̣ lâp̣ phần cứng và hê ̣ điều hành. Đây là khả năng môṭ chương triǹ h đươc̣ viết ta ị môṭ máy nhưng có thể chaỵ đươc̣ bất kỳ đâu
  9. Tiń h đôc̣ lâp̣ với phần cứng đươc̣ hiểu theo nghiã môṭ chương triǹ h J a va nếu chaỵ đúng trên phần cứng của môṭ ho ̣máy nào đó thi ̀ nó cũng chaỵ đúng trên tất cả các ho ̣máy khác. Môṭ chương triǹ h chi ̉ chaỵ đúng trên môṭ số ho ̣ máy cu ̣ thể đươc̣ goị là phu ̣thuôc̣ vào phần cứng. Tiń h đôc̣ lâp̣ với hê ̣ điều hành đươc̣ hiểu theo nghiã môṭ chương triǹ h Java có thể chaỵ đươc̣ trên tất cả
  10. các hê ̣điều hành. Môṭ chương triǹ h chi ̉ chaỵ đươc̣ trên môṭ số hê ̣ điều hành đươc̣ goị là phu ̣ thuôc̣ vào hê ̣điều hành. Cá c chươn g trình viết bằng java có thể chaỵ trên hầu hế t cá c h ê ̣ nề n mà không cần phải thay đổi gi,̀ điều này đa ̃ đươc̣ những người lâp̣ triǹ h đăṭ cho nó môṭ khẩu hiêụ ‘viế t môṭ lầ n, chaỵ moị nơi’, điều này là không thể có với các ngôn ngữ lâp̣ triǹ h khác. Đối với các chương triǹ h
  11. viết bằng C, C++ hoăc̣ môṭ ngôn ngữ nào khác, triǹ h biên dic̣ h sẽ chuyển tâp̣ lêṇ h thành ma ̃ máy (machine code), hay lêṇ h của bô ̣ vi xử lý. Những lêṇ h này phu ̣ thuôc̣ vào CPU hiêṇ taị trên máy baṇ . Nên khi muốn chaỵ trên loaị CPU khác, chúng ta phải biên dic̣ h laị chương triǹ h. 4. Maṇ h mẽ Java là ngôn ngữ yêu cầu chăṭ chẽ về kiểu dữ liêụ , viêc̣ é p kiể u tư ̣ đôṇ g bừa bãi của C, C++
  12. nay đươc̣ haṇ chế trong Java, điề u này làm chương triǹ h rõ ràng, sáng sủa, it́ lỗi hơn.Java kiểm tra lúc biên dic̣ h và cả trong thời gian thông dic̣ h vi ̀ vâỵ Java loaị bỏ môṭ môṭ số loaị lỗi lâp̣ triǹ h nhất điṇ h.Java không sử duṇ g con trỏ và các phép toán con trỏ. Java kiểm tra tất cả các truy nhâp̣ đến mảng, chuỗi khi thưc̣ thi để đảm bảo rằng các truy nhâp̣ đó không ra ngoài giới haṇ kić h thước.
  13. Trong các môi trường lâp̣ triǹ h truyền thống, lâp̣ triǹ h viên phải tư ̣ miǹ h cấp phát bô ̣ nhớ. Trước khi chương triǹ h kết thúc thi ̀ phải tư ̣ giải phóng bô ̣nhớ đã cấp. Vấn đề nảy sinh khi lâp̣ triǹ h viên quên giải phóng bô ̣ nhớ đã xin cấp trước đó. Trong chương triǹ h Java, lâp̣ triǹ h viên không phải bâṇ tâm đến viêc̣ cấp phát bô ̣ nhớ. Qúa triǹ h cấp phát, giải phóng đươc̣ thưc̣ hiêṇ tư ̣
  14. đôṇ g, nhờ dic̣ h vu ̣ t h u nhăṭ những đối tươṇ g không còn sử duṇ g nữa (garbage collection). Cơ chế bâỹ lỗi của Java giúp đơn giản hóa qúa triǹ h xử lý lỗi và hồi phuc̣ sau lỗi. 5. Hỗ trơ ̣lâp̣ trình đa tuyế n Đây là tiń h năng cho phép viết môṭ chương triǹ h có nhiều đoaṇ ma ̃ lêṇ h đươc̣ chaỵ song song với nhau. Với java ta có thể viết các chương triǹ h có khả năng chaỵ song song môṭ cách dễ dàng, hơn thế nữa viêc̣ đồng
  15. bô ̣ tài nguyên dùng chung trong Java cũn g rấ t đơng giản. Điều này là không thể có đối với môṭ số ngôn ngữ lâp̣ triǹ h khác như C/C++, pascal 6. Phân tá n Java hỗ trơ ̣ đầy đủ các mô hiǹ h tiń h toán phân tán: mô hiǹ h client/server, goị thủ tuc̣ từ xa 7. Hỗ trơ ̣internet Muc̣ tiêu quan troṇ g của các nhà thiết kế java là taọ điều
  16. kiêṇ cho các nhà phát triển ứng duṇ g có thể viết các chương triǹ h ứng duṇ g internet và web môṭ cách dễ dàng, với java ta có thể viết các chương triǹ h sử duṇ g các giao thức TCP, UDP môṭ cách dễ dàng, về lâp̣ triǹ h web phiá máy khách java có công nghê ̣ java applet, về lâp̣ trình web phía má y khách j a va c ó c ô n g nghê ̣ servlet/JSP, về lâp̣ triǹ h phân tán java có công nghê ̣ RMI, CORBA, EJB, Web Service.
  17. 8. Thông dic̣h Cá c chươn g trình java cầ n đươc̣ thông dic̣ h trước khi chaỵ , môṭ chương triǹ h java đươc̣ biên dic̣ h thành mã byte code ma ̃ đôc̣ lâp̣ với hê ̣ nền, chương triǹ h thông dic̣ h java sẽ ánh xa ̣ ma ̃ byte code này lên mỗi nền cu ̣ thể, điều này khiến java châṃ chap̣ đi phần nào. III. Cá c kiể u ứ ng duṇ g Java
  18. Với Java ta có thể xây dưṇ g cá c kiểu ứ ng duṇ g sau: 1. Ứ ng duṇ g Applets Applet là chương triǹ h Java đươc̣ taọ ra để sử duṇ g trên Internet thông qua các triǹ h duyêṭ hỗ trơ ̣ Java như IE hay Netscape. Applet đươc̣ nhúng bên trong trang Web. Khi trang Web hiển thi ̣trong triǹ h duyêṭ, Applet sẽ đươc̣ tải về và thưc̣ thi taị triǹ h duyêṭ. 2. Ứ ng duṇ g dò ng lêṇ h (console)
  19. Các chương triǹ h này chaỵ từ dấu nhắc lêṇ h và không sử duṇ g giao diêṇ đồ hoạ . Các thông tin nhâp̣ xuất đươc̣ thể hiêṇ taị dấu nhắc lêṇ h. 3. Ứ ng duṇ g đồ hoạ Đây là các chương triǹ h Java chaỵ đôc̣ lâp̣ cho phép người dùng tương tác qua giao diêṇ đồ hoạ . 4. JSP/Servlet Java thić h hơp̣ để phát triển ứng duṇ g nhiều lớp. Applet là chương triǹ h đ ồ hoạ chaỵ trên
  20. triǹ h duyêṭ taị máy traṃ . Ở các ứng duṇ g Web, máy traṃ gử i yêu cầu tới máy chủ. Máy chủ xử lý và gử i kết quả trở laị máy traṃ . Các Java API chaỵ trên máy chủ chiụ trách nhiêṃ xử lý taị máy chủ và trả lời các yêu cầu của máy traṃ . Các Java API chaỵ trên máy chủ này mở rôṇ g khả năng của các ứng duṇ g Java API chuẩn. Các ứng duṇ g trên máy chủ này đươc̣ goị là các JSP/Servlet. hoăc̣ Applet taị máy chủ. Xử lý
  21. Form của HTML là cách sử duṇ g đơn giản nhất của JSP/Servlet. Chúng còn có thể đươc̣ dùng để xử lý dữ liêụ , thưc̣ thi các giao dic̣ h và thường đươc̣ thưc̣ thi thông qua máy chủ Web. 5. Ứ ng duṇ g cơ sở dữ liêụ Cá c ứng duṇ g này sử duṇ g JDBC API để kế t nối tới cơ sở dữ liêụ . Chúng có thể là Applet hay ứng duṇ g, nhưng Applet bi ̣giới haṇ
  22. bởi tiń h bảo mâṭ. 6. Ứ ng duṇ g maṇ g Java là môṭ ngôn ngữ rất thić h hơp̣ cho viêc̣ xây dưṇ g các ứng duṇ g maṇ g. Với thư viêṇ Socket baṇ có thể lâp̣ triǹ h với hai giao thức: UDP và TCP. 7. Ứ ng duṇ g nhiều tầ ng Với Java baṇ có thể xây dưṇ g phân tán nhiều tầng với nhiều hỗ trơ ̣ khác nhau như: RMI, CORBA, EJB, Web Service 8. Ứ ng duṇ g cho cá c thiế t bi ̣
  23. di đôṇ g Hiêṇ nay phần lớn các thiết bi ̣ di đôṇ g như: Điêṇ thoaị di đôṇ g, máy trơ ̣ giúp cá nhân đều hỗ trơ ̣ Java. Thế nên baṇ có thể xây dưṇ g các ứng duṇ g chaỵ trên các thiết bi ̣ di đôṇ g này. Đây là môṭ kiểu ứng duṇ g khá hấp dãn, bởi vi ̀ các thiết bi ̣ di đôṇ g này ngày càng phổ biến và nhu cầu có các ứng duṇ g chaỵ trên đó, đăc̣ biêṭ là các ứng duṇ g mang tiń h chất giải trí như game
  24. IV. Má y ả o Java (JVM- Java Virtual Machine) Máy ảo là môṭ phần mềm mô phỏng môṭ máy tiń h thâṭ (máy tiń h ảo). Nó có tâp̣ hơp̣ các lêṇ h logic để xác điṇ h các hoaṭ đôṇ g của máy tiń h và có môṭ hê ̣điều hành ảo. Người ta có thể xem nó như môṭ máy tiń h thâṭ (máy tiń h có phần cứng ảo, hê ̣ điều hành ảo). Nó thiết lâp̣ các lớp trừu tươṇ g cho: Phần cứng bên dưới, hê ̣ điều
  25. hành, mã đã biên dic̣ h. Triǹ h biên dic̣ h chuyển mã nguồn thành tâp̣ các lêṇ h của máy ảo mà không phu ̣ thuôc̣ vào phần cứng và hê ̣ điều hành cu ̣ thể. Triǹ h thông dic̣ h trên mỗi máy sẽ chuyển tâp̣ lêṇ h này thành chương triǹ h thưc̣ thi. Máy ảo taọ ra môṭ môi trường bên trong để thưc̣ thi các lêṇ h bằng cách: 1 Nap̣ các file .class 2 Quản lý bô ̣nhớ
  26. 3 Doṇ “rác” Viêc̣ không nhất quán của phần cứng làm cho máy ảo phải sử duṇ g ngăn xếp để lưu trữ các thông tin sau: 1 Các “Frame” chứa các traṇ g thái của các phương thức. 2 Các toán haṇ g của mã bytecode. 3 Các tham số truyền cho phương thức. 4 Các biến cuc̣ bô.̣ Khi JVM thưc̣ thi mã, môṭ thanh ghi cuc̣ bô ̣ có tên
  27. “Program Counter” đươc̣ sử duṇ g. Thanh ghi này trỏ tới lêṇ h đang thưc̣ hiêṇ . Khi cần thiết, có thể thay đổi nôị dung thanh ghi để đổi hướng thưc̣ thi của chương triǹ h. Trong trường hơp̣ thông thườ ng thì từng lêṇ h môṭ nối tiếp nhau sẽ đươc̣ thưc̣ thi. Môṭ khái niêṃ thông duṇ g khác trong Java là triǹ h biên dic̣ h “Just In Time-JIT” . Các triǹ h duyêṭ thông duṇ g như Netscape hay IE đều có JIT bên
  28. trong để tăng tốc đô ̣ thưc̣ thi chương triǹ h Java. Muc̣ đić h chiń h của JIT là chuyển tâp̣ lêṇ h bytecode thành mã máy cu ̣ thể cho từng loaị CPU. Các lêṇ h này sẽ đươc̣ lưu trữ và sử duṇ g mỗi khi goị đến. BÀI 2 NỀN TẢ NG CỦ A JAVA I. Tâp̣ ký tư ̣dù ng trong java Moị ngôn ngữ nói chung, ngôn ngữ lâp̣ triǹ h nói riêng đều phải xây dưṇ g trên môṭ tâp̣ hơp̣
  29. chữ cái (hay còn goị là bảng chữ cái), các ki ́ tư ̣ đươc̣ nhóm laị theo môṭ cách nào đó để taọ thành các từ, các từ laị đươc̣ nhóm laị thành các câu (trong ngôn ngữ lâp̣ triǹ h goị là câu lêṇ h), môṭ chương triǹ h máy tiń h tiń h là môṭ tâp̣ các câu lêṇ h đươc̣ bố trí theo môṭ trâṭ tư ̣ mà người viết ra chúng sắp đăṭ Ngôn ngữ java đươc̣ đươc̣ xây dưṇ g trên bảng chữ cái unicode, do vâỵ ta có thể dùng
  30. các ki ́ tư ̣unicode để đăṭ tên cho các điṇ h danh. II. Từ khoá củ a Java Mỗi ngôn ngữ lâp̣ triǹ h có môṭ tâp̣ các từ khoá, người lâp̣ triǹ h phải sử duṇ g từ khoá theo đúng nghiã mà người thiết kế ngôn ngữ đa ̃ đề ra, ta không thể điṇ h nghiã laị nghiã của các từ khoá, như sử duṇ g nó để đăṭ tên biến, hàm Sau đây là môṭ số từ khoá thườ ng găp̣ :
  31. Tư ̀ Mô tả khó a Sử duṇ g để khai abstractbáo lớp, phương thức trừu tươṇ g ̉ boolean Kiêu dữ liêụ logic Đươc̣ sử duṇ g để ́ break kêt thúc vòng lăp̣ hoăc̣ cấu trúc switch ̉ ́ byte kiêu dữ liêụ sô nguyên
  32. case đươc̣ sử duṇ g trong lêṇ switch Chưa đươc̣ sử cast duṇ g (để dành cho tương lai) catch đươc̣ sử duṇ g trong xử lý ngoaị lê ̣ ̉ char kiêu dữ liêụ ký tư ̣ ̉ class Dùng đê khai báo lớp Chưa đươc̣ const
  33. dùng đươc̣ dùng continue trong vòng lăp̣ để bắt đầu môṭ vòng lăp̣ mới đươc̣ sử duṇ g default trong lêṇ h switch đươc̣ dùng do trong vòng lăp̣ điều kiêṇ sau ̉ double kiêu dữ liêụ số thưc̣
  34. else khả năng lưạ choṇ thứ hai trong câu lêṇ h if chi ̉ rằng môṭ ́ extends lớp đượ c kê thừa từ môṭ lớp khác false Giá tri ḷ ogic Dùng để khai báo hằng số, phương thức final không thể ghi đè, hoăc̣ lớp không thể kế
  35. thừa phần cuối finally của khối xử lý ngoaị lê ̣ float kiểu số thưc̣ for Câu lêṇ h lăp̣ goto Chưa đươc̣ dùng if Câu lêṇ h lưạ choṇ chi ̉ rằng môṭ implementslớp triển khai từ môṭ giao diêṇ
  36. import Khai báo sử duṇ g thư viêṇ kiểm tra môṭ đối tươṇ g có instanceof phải là môṭ thể hiêṇ của lớp hay không sử duṇ g để interface khai báo giao diêṇ kiểu số long nguyên Khai báo
  37. phương thức native đươc̣ viết bằng ngông ngữ biên dic̣ h C++ ́ new taọ môṭ đôi tươṇ g mới môṭ đối null tươṇ g không tồn taị ̉ package Dùng đê khai báo môṭ gói đăc̣ tả truy private xuất
  38. protected đăc̣ tả truy xuất public đăc̣ tả truy xuất Quay từ return phương thức về chỗ goị nó ̉ ́ short kiêu sô nguyên Dùng để static khai báo biến, thuôc̣ tiń h tiñ h
  39. super Truy xuất đến lớp cha switch lêṇ h lưạ choṇ môṭ phương thức synchronizedđôc̣ quyền truy xuất trên môṭ đối tươṇ g ́ ̉ this Am chi chiń h lớp đó Ném ra throw ngoaị lê ̣
  40. Khai bao throws ́ phương thức ném ra ngoaị true lê ̣ Giá tri ḷ ogic ̉ try sử duṇ g đê bắt ngoaị lê ̣ Dùng để khai báo môṭ void phương thức không trả về giá tri ̣ while Dùng trong cấu trúc lăp̣
  41. III. Điṇ h danh (tên) Tên dùng để xác điṇ h duy nhất môṭ đaị lươṇ g trong chương triǹ h. Trong java tên đươc̣ đăṭ theo quy tắc sau: - Không trùng với từ khoá - Không bắt đầu bằng môṭ số, tên phải bắt đầu bằng ki ́ tư ̣ hoăc̣ bắt đầu bằng kí $,_ - Không chứa dấu cách, các ki ́ tư ̣toán hoc̣ như +, -, *,/, % - Không trùng với môṭ điṇ h danh khác trong cùng môṭ
  42. phaṃ vi chú ý : - Tên nên đăṭ sao cho có thể mô tả đươc̣ đối tươṇ g trong thưc̣ tế - Giống như C/C++, java có phân biêṭ chữ hoa chữ thường - Trong java ta có thể đăṭ tên với đô ̣dài tuỳ ý - Ta có thể sử duṇ g các ki ́ tư ̣ tiếng viêṭ để đăṭ tên Quy ướ c về đăṭ tên trong java
  43. Ta nên đăṭ tên biến, hằng, lớp, phương thức sao cho nghiã của chúng rõ ràng, dễ hiểu, khoa hoc̣ và mang tiń h ước lê ̣ quốc tế. Do java có phân biêṭ chữ hoa, chữ thường nên ta phải cẩn thâṇ và chú ý. Sau đây là quy ước đăṭ tên trong java (chú ý đây chi ̉ là quy ước do vâỵ không bắt buôc̣ phải tuân theo quy ước này): • Đối với biến và phương thức thi ̀ tên bao giờ cũng bắt đầu
  44. bằng ký tư ̣ thườ ng, nếu tên có nhiều từ thi ̀ ghép laị thi:̀ ghép tất cả các từ thành môṭ, ghi từ đầu tiên chữ thường, viết hoa ki ́ tư ̣ đầu tiên của mỗi từ theo sau trong tên, ví du ̣ a r e a , radius, readInteger - Đối với tên lớp, giao diêṇ ta viết hoa các ki ́ tư ̣ đầu tiên của mỗi từ trong tên, ví du ̣lớp WhileTest, Circle • Tên hằng bao giờ cũng viết hoa, nếu tên gồm nhiều từ thì
  45. chúng đươc̣ nối với hau bởi kí tư ̣ ghac̣ h dưới ‘_’, vi ́ du ̣ PI, MAX_VALUE IV. Cấ u trú c môṭ chương trình java - Mỗi ứng duṇ g Java bao gồm môṭ hoăc̣ nhiều đơn vi ḅ iên dic̣ h (mỗi đơn vi ̣ biên dic̣ h là môṭ têp̣ tin có phần mở rôṇ g Java) - Mỗi đơn vi ̣ biên dic̣ h bao gồm môṭ hoăc̣ nhiều lớp - Mỗi ứng duṇ g đôc̣ lâp̣ phải có duy nhất môṭ phương thức
  46. main (điểm bắt đầu của ứng duṇ g) - Mỗi đơn vi ̣ biên dic̣ h có nhiều nhất môṭ lớp đươc̣ khai báo là public, nếu như trong đơn vi ̣biên dic̣ h có lớp public thi ̀ tên của đơn vi ḅ iên dic̣ h phải trùng với t ê n của lớp public (giống hêṭ nhau cả ký tư ̣ hoa lâñ ký tư ̣thường) - Bên trong thân của mối lớp ta khai báo các thuôc̣ tiń h, phương thức của lớp đó, Java là ngôn ngữ hướng
  47. đối tươṇ g, do vâỵ ma ̃ lêṇ h phải nằm trong lớp nào đó . Mỗi lêṇ h đều đươc̣ kết thú c bằn g dấu chấm phảy “;”. • Trong ngôn ngữ Java, lớp là môṭ đơn vi ṃ âũ có chứa dữ liêụ và mã lêṇ h liên quan đến môṭ thưc̣ thể nào đó. Khi xây dưṇ g môṭ lớp, thưc̣ chất baṇ đang taọ ra môṭ môṭ kiểu dữ liêụ . Kiểu dữ liêụ mới này đươc̣ sử duṇ g để xác điṇ h các biến mà ta thương goị là
  48. “đối tươṇ g”. Đối tươṇ g là các thể hiêṇ (instance) của lớp. Tất cả các đối tươṇ g đều thuôc̣ về môṭ lớp có chung đăc̣ tiń h và hành vi. Mỗi lớp xác điṇ h môṭ thưc̣ thể, trong khi đó mỗi đối tươṇ g là môṭ thể hiêṇ thưc̣ sư.̣ - Khi ban khai báo môṭ lớp, baṇ cần xác điṇ h dữ liêụ và các phương thức của lớp đó . Về cơ bản môṭ lớp đươc̣ khai báo như sau: Cú phá p:
  49. class classname { var_datatype variablename; : met_datatype methodname(parameter_list) : } Trong đó : class - Từ khoá xá c điṇ h lớ p classname - Tên củ a lớ p var_datatype - kiể u dữ liêụ củ a biế n variablename - Tên củ a biế n
  50. met_datatype - Kiể u dữ liêụ trả về củ a phương thứ c methodname - Tên củ a phương thứ c parameter_list – Cá c tham số đươc̣ củ a phương thứ c - Baṇ còn có thể điṇ h nghiã môṭ lớp bên trong môṭ lớp khác. Đây là lớp xếp lồng nhau, các thể hiêṇ (instance) của lớp này tồn taị bên trong thể hiêṇ của môṭ lớp che phủ chúng. Nó chi phối viêc̣ truy nhâp̣ đến các
  51. thành phần của lớp bao phủ chúng. Có hai loaị lớp trong đó là lớp trong tiñ h “static” và lớp trong không tiñ h “non static” + Lớp trong tiñ h (static) Lớp trong tiñ h đươc̣ điṇ h nghiã với từ khoá “static”. Lớp trong tiñ h có thể truy nhâp̣ vào các thành phần tiñ h của lớp phủ nó. + Lớp trong không tiñ h (non static) Lớp bên trong (không phải là lớp trong tiñ h) có thể truy nhâp̣
  52. tất cả các thành phần của lớp bao nó, song không thể ngươc̣ laị. V. Chương trình JAVA đầ u tiên Để có thể biên dic̣ h và chaỵ các chương triǹ h java ta phải cài • J R E (Java Runtime Enviroment) môi trường thưc̣ thi của java, nó bao gồm : JVM (Java Virtual Machine) máy ảo java vi ̀ các chương triǹ h java đươc̣ thông
  53. dic̣ h và chaỵ trên máy ảo java và tâp̣ các thư viêṇ cần thiết để chaỵ các ứng duṇ g java. • Bô ̣công cu ̣ biên dic̣ h và t h ô n g dic̣ h JDK của Sun Microsystem Sau khi cài đăṭ JDK (giả sử thư muc̣ cài đăṭ là C:\JDK1.4) t a sẽ nhâ ṇ đươc̣ môṭ cấu trúc thư muc̣ như sau:
  54. - Để biên dic̣ h môṭ chương triǹ h java sang mã byte code ta dùng lêṇ h C:\JDK1.4\BIN\javac TênTêp̣ .java - Để thông dic̣ h và chaỵ chương triǹ h ta sử duṇ g lêṇ h C:\JDK1.4\BIN\java TênTêp̣ Đ ể biên dic̣ h v à chaỵ chương triǹ h Java đơn giản t a nên thiế t đă ṭ hai biến môi trường “paht” và “classpath” như sau: - Đối với dòng WinNT:
  55. + R-Click vào My ComputerÆ choṇ PropertiesÆ choṇ AdvancedÆEnviroment Variables
  56. + Trong phầ n System variables choṇ new để thêm biến môi trường mới, trong hôp̣ thoaị hiêṇ ra gõ “classpath” và o ô Variable Name và “.;C:\jdk1.4\lib\tools.jar;C:\jdk1.4 trong ô variable value (chú ý không gõ dấu “ vào, muc̣ đić h để cho dễ nhiǹ mà thôi)
  57. + Cũn g tr ong phần System variables tìm đến phầ n p a t h trong danh sáchÆchoṇ edit để sử a laị giá tri ̣ hiêṇ có, trong ô value ta thêm vào cuối “;C:\jdk1.4\bin” Công viêc̣ đăṭ các biến môi trường đã xong, để thấy đươc̣ tác duṇ g của c á c biến môi trường ta cần phải khởi đôṇ g laị máy - Đối với dòng Win9X: Mở têp̣ C:\Autoexec.bat sau đó thêm vào hai dòng sau:
  58. +classpath=.;C:\jdk1.4\lib\tools.jar;C:\ r + path= ;c:\jdk1.4\bin Khởi đôṇ g laị máy để thấy đươc̣ tác duṇ g của các biến môi trường này Vi ́ du ̣ đầu tiên: chương triǹ h Hello World (chương triǹ h khi chaỵ sẽ in ra màn hiǹ h lời chào Hello World) Các bước: • Mở môṭ chương triǹ h soaṇ thảo văn bản hỗ trơ ̣ asciii, như notepad, wordpad,
  59. EditPlus và gõ vào các dòng sau: public class HelloWorld { p ublic static void main(String[] args){ System.out.println("Hello World"); } } • Ghi laị với cái tên C:\HelloWorld.java (chú ý tên têp̣ phải trùng với tên lớp, kể cả chữ hoa chữ thường, phần
  60. mở rôṇ g là java) - Mở của sổ DOS Prompt + chuyển vào thư muc̣ C:\ + Gõ lêṇ h javac HelloWorld.java để biên dic̣ h chương triǹ h, nếu viêc̣ biên dic̣ h thành công (chương triǹ h không có lỗi cú pháp) thì ta sẽ thu đươc̣ têp̣ HelloWorld.class trong cùng thư muc̣ , nếu trong chương triǹ h còn lỗi cú pháp thi ̀ trong bứơc này ta sẽ nhâṇ đươc̣ môṭ thông
  61. báo lỗi và lúc n à y tê ̣ p HelloWorld.class cũng không đươc̣ taọ ra + Gõ lêṇ h java HelloWorld (chú ý không gõ phần mở rôṇ g) để chaỵ chương triǹ h HelloWorld. Sau khi thông dic̣ h và chaỵ ta nhâṇ đươc̣
  62. VI. Chú thí ch trong chương trình Trong java ta có 3 cách để ghi chú thić h Cách 1: sử duṇ g căp̣ /* và */ ý nghiã của căp̣ chú thić h này giống như của C, C++ Cách 2: sử duṇ g căp̣ // ý nghiã của căp̣ chú thić h này giống như của C, C++ Cách 3: sử duṇ g căp̣ / và */, đây là kiểu chú thić h tài liêụ (không có trong
  63. C/C++), nó dùng để taọ ra tài liêụ chú thić h cho chương triǹ h. Với cách thứ nhất và cách ba ta có thể viết chú thić h trên nhiều dòng, với cách chú thić h hai ta chi ̉ có thể chú thić h trên môṭ dòng. Chú ý : trong java ta có thể đăṭ chú thić h ở đâu?, câu trả lời là: ở đâu có thể đăṭ đươc̣ môṭ dấu cách thi ̀ ở đó có thể đăṭ chú thić h. VII. Kiể u dữ liêụ
  64. 1. Cá c kiể u dữ liêụ nguyên thuỷ Tư Kích ̀ Mô tả khoá cỡ thiểu (kiểu số nguyên) số byte nguyên 8 bit môṭ byte số 16 short nguyên bit ngắn số 32 int nguyên bit
  65. long số 64 nguyên dai bit ̀ (kiểu số thưc̣ ) kiểu thưc̣ vơi 32 float ́ đô ̣ chiń h bit xác đơn Double- precision 64 double floating bit point (kiểu khá c) kiểu kí 16 char tư ̣ bit 0
  66. true kiểu boolean hoăc - logic ̣ false void - - - Đăc̣ điểm của các biến có kiểu nguyên thủy là vùng nhớ của chúng đươc̣ cấp phát ở phần stack. Do vâỵ viêc̣ truy xuất vào môṭ biế n kiểu nguyên thủy rất nhanh. 2. Kiể u tham chiế u Trong Java có 3 kiểu dữ liêụ tham chiếu
  67. Kiểu dữ Mô ta liêụ ̉ Tâp hơp cac Mang ̣ ̣ ́ ̉ dư liêu cung (Array) ̃ ̣ ̀ kiểu. Là sư ̣cài đăṭ Lớp mô tả về môṭ đối (Class) tươṇ g trong bài toán. Là môṭ lớp thuần trừu tươṇ g Giao diêṇ đươc̣ taọ ra cho (Interface) phép cài đăṭ đa thừa kế
  68. trong Java. Đăc̣ điểm của các biến kiểu tham chiếu là nó chứa điạ chỉ của đối tươṇ g mà nó trỏ đến. Vùng nhớ của biến tham chiếu đươc̣ cấp phát ở vùng nhớ stack còn vùng nhớ của đối tươṇ g đươc̣ cấp phát ở vùng nhớ heap. Viêc̣ truy xất vào vùng nhớ heap châṃ hơn truy xất vào vùng nhớ stack tuy nhiên java
  69. c ó cơ chế cho phép truy câp̣ vào vùng nhớ heap với tốc đô ̣ xấp xi ̉ bằng tốc đô ̣truy câp̣ vào vùng nhớ stack. VIII. Khai bá o biế n 1. Khai bá o biế n Tương tư ̣ ngôn ngữ C/C++, để khai báo biến trong java ta sử duṇ g cú pháp sau: type name [=InitValue]; trong đó: • type là kiểu dữ liêụ cuả
  70. biến • name là tên của biến, tên biến là môṭ xâu ki ́ tư ̣ đươc̣ đăṭ theo quy tắc đăṭ tên của java • InitValue là giá tri ̣khởi taọ cho biến, đây là phần tuỳ choṇ , nếu bỏ qua phần này thi ̀ giá tri ̣ ban đầu của biến đươc̣ khởi taọ giá tri ṃ ăc̣ điṇ h Chú ý : - Nếu cần khai báo nhiều biến có cùng môṭ kiểu dữ liêụ ta
  71. có thể đăṭ các khai báo các biến trên môṭ dòng, các biến này đươc̣ phân cách nhau bởi dấu phảy - Java sẽ xử lý các biến không đươc̣ khởi đầu giá tri ṇ hư sau: + Đối với thuôc̣ tiń h (biến đươc̣ khai báo trong phaṃ vi của lớp) thi ̀ Java sẽ tư ̣đôṇ g khởi gán giá tri ̣cho các biến theo quy tắc sau: + giá tri 0̣ cho kiểu dữ liêụ số + false cho kiểu logic
  72. + ki ́ tư ̣null (mã 0) cho ki ́ tư ̣ + giá tri ̣ null cho kiểu đối tươṇ g + Đối với các biến cuc̣ bô ̣thì biến không đươc̣ khới gán giá tri ̣măc̣ điṇ h, tuy nhiên Java sẽ báo lỗi nếu ta sử duṇ g môṭ biến chưa đươc̣ nhâṇ giá tri ̣ 2. phaṃ vi biế n Mỗi biến đươc̣ khai báo ra có môṭ phaṃ vi hoaṭ đôṇ g, phaṃ vi của biến là nơi mà biến có thể đươc̣ truy câp̣ , điều này xác điṇ h cả tiń h thấy đươc̣ và
  73. thời gian sống của biến. • biế n pha ṃ vi lớp là biế n đươc̣ khai báo bên trong lớp nhưng bên ngoài các
  74. phương thức và hàm taọ , tuy nhiên viêc̣ khai báo phải xuất hiêṇ trước khi biến đươc̣ sử duṇ g • biến phaṃ vi cuc̣ bô ̣ là biến đươc̣ khai báo bên trong môṭ khối, phaṃ vi của biến tiń h từ điểm biến đươc̣ khai báo cho đến cuối khối mà biế n đươc̣ khai báo Vi ́ du:̣ { int i=1; // chi ̉ có i săñ sàng sử duṇ g
  75. { int j=10; // cả i và j đều săñ sàng } // chi ̉ có i săñ sàng // j không săñ sàng vi ̀ nằm ngoài phaṃ vi } Chú ý : Ta không thể là m điều sau cho dù nó có thể trong C/C++ {
  76. int i=1; { int i=10;// không đươc̣ phép vi ̀ đã có môṭ biến cùng tên với nó } } những người thiết kế java cho rằng điều đó có thể gây lần lôṇ , do vâỵ ho ̣đa ̃ quyết điṇ h không cho phép che giấ u môṭ biến ở phaṃ vi lớn hơn. Chú ý: thời gian sống của
  77. các đối tươṇ g không tuân theo quy luâṭ thời gian sống của các biến kiểu nguyên thuỷ. VII. Môṭ số phé p toá n trên kiể u dữ liêụ nguyên thuỷ 1. Phé p gá n Cú pháp Biến=BiểuThức; Phép gán đươc̣ thưc̣ hiêṇ bằng toán tử ‘=’, nó có nghiã là “ haỹ tiń h toán giá tri ̣ biểu thức bên phải dấu gán, sau đó đưa giá tri đ̣ ó vào ô nhớ có tên nằm ở bên trái dấu gán’
  78. Chú ý : + câu lêṇ h gán gồm môṭ dấu ‘=’ + kiểu của biểu thức bên phả i dấu gán phải tương thić h với kiểu dữ liêụ của biến + trong java ta có thể thưc̣ hiêṇ môṭ dâỹ gán như sau: i = j = 10;// cả i và j đều có giá tri 1̣ 0 2. Toá n tử toá n hoc̣ Ngôn ngữ java cũng có các phép toán số hoc̣ như các ngôn ngữ khác: + ( phép côṇ g), - (
  79. phép trừ ), * ( phép nhân ),/ ( phép chia ), % ( phép toán chia lấy phần nguyên) Ta mô tả tóm tắt các phép toán số hoc̣ qua bảng tổng kết sau: Phep Sư ́ ̉ Mô tả toá n duṇ g op1 Công op1 + ̣ + op2 vớiop2 op1 Trư op1 cho - ̀ - op2 op2
  80. * op1 Nhân op1 * oopp21/ vớic ohpia2 op1 / op2 cho op2 Tiń h phần op1 dư cua phep % ̉ ́ % op2 chia op1 cho op2 3. Toá n tử tăng, giả m Giống như ngôn ngữ C/C++, java cũng có phép toán tăng, giảm, ta có thể mô tả tóm tắt qua các bằng sau: Phep Sư ́ ̉ Mô tả
  81. toá n duṇ g Tăng op lên 1 đơn vi,̣ giá tri c̣ ủa op ++ op++ đươc̣ tăng lên trước khi biểu thức chứa nó đươc̣ tiń h Tăng op lên 1 đơn vi,̣ giá tri c̣ ủa op đươc̣ tăng lên ++ ++op sau khi biểu thức
  82. chứa nó đươc tiń h G̣iảm op xuống1 đơn vi, ̣ giá tri c̣ ủa op đươc̣ giảm op xuống trước khi biểu thức chứa nó đươc̣ tiń h Giảm op xuống1 đơn vi, ̣ giá tri ̣
  83. của op op đươc̣ giảm xuống sau khi biểu thức chứa nó đươc̣ tiń h Chú ý : nế u toá n tử tăng trướ c, tăng sau(giả m trướ c, giả m sau) đứ ng môṭ mình(không nằm trong biểu thức ) thi ̀ chúng hoaṭ đôṇ g như nhau, chúng chi ̉ khác nhau khi chúng nằm trong biểu thức
  84. 4. Phé p toá n quan hê ̣ Phép toán quan hê ̣ bao giờ cũng cho kết quả boolean, phép toán quan hê ̣sẽ so sánh 2 giá tri, ̣ nó xác điṇ h mối quan hê ̣giữa chúng, vi ́ du!̣ = sẽ trả về true nếu 2 toán haṇ g là khác nhau. Ta tóm tắt các phép toán qua bảng sau: Nhâṇ về Phep Sư ́ ̉ giá tri ̣true toá n duṇ g khi
  85. op1 op1 lơn hơn > ́ > op2 op2 op1 op1 lơn hơn >= ́ >= op2 hoăc̣ bằng op2 op1 op1 nho < ̉ < op2 hơn op2 op1 nho op1 ̉ <= hơn hoăc bằng <= op2 ̣ op2 op1 op1 bằng == == op2 op2 op1! op1 khac != ́
  86. = op2 op2 Vi ́ du ̣ sử duṇ g các phép toán quan hê ̣ public class RelationalDemo { public static void main(String[] args) { // a few numbers int i = 37; int j = 42; int k = 42; System.out.println("Variable values "); System.out.println(" i = " + i); System.out.println(" j = " + j); System.out.println(" k
  87. = " + k); //greater than System.out.println("Greater than "); System.out.println(" i > j = " + (i > j)); // false System.out.println(" j > i = " + (j > i));// true System.out.println(" k > j = " + (k > j));// false, they are equal //greater than or equal to System.out.println("Greater than or equal to "); System.out.println(" i >= j = " +
  88. (i >= j));// false System.out.println(" j >= i = " + (j >= i));// true System.out.println(" k >= j = " + (k >= j));// true //less than System.out.println("Less than "); System.out.println(" i < j = " + (i < j));// true System.out.println(" j < i = " + (j < i));// false System.out.println(" k < j = " + (k < j));// false //less than or equal to
  89. System.out.println("Less than or equal to "); System.out.println(" i <= j = " + (i <= j));// true System.out.println(" j <= i = " + (j <= i));// false System.out.println(" k <= j = " + (k <= j));// true //equal to System.out.println("Equal to "); System.out.println(" i == j = " + (i == j));// false System.out.println(" k == j = " + (k == j));// true
  90. //not equal to System.out.println("Not equal to "); System.out.println(" i! = j = " + (i! = j));// true System.out.println(" k! = j = " + (k! = j));// false } } Đây là đầu ra của chương triǹ h Variable values i = 37 j = 42
  91. k = 42 Greater than i > j = false j > i = true k > j = false Greater than or equal to i >= j = false j >= i = true k >= j = true Less than i < j = true j < i = false k < j = false Less than or equal to i <= j = true j <= i = false k <= j = true Equal to i == j = false k == j = true Not equal to
  92. i! = j = true k! = j = false 5. Phé p toá n logic Java hỗ trơ ̣6 phép toán logic đươc̣ chi ̉ ra trong bảng sau: Phép Sử Nhâṇ về giá toá n duṇ g tri ̣true khi Cả op1 và op2 đều la true, op1 ̀ gia tri c̣ ua op2 && && ́ ̉ chỉ đươc̣ tiń h op2 khi op1 là true
  93. Hoăc̣ op1 hoăc̣ op2 là op1 || true, giá tri c̣ ủa || op2 op2 chi ̉ đươc̣ tiń h khi op1 là ! false ! op la false op ̀ Cả op1 và op2 đều là true, op1 gia tri c̣ ua op2 & ́ ̉ & op2 luôn đươc̣ tiń h kể cả khi
  94. op1H loaằ fcạ lospe1 hoăc̣ op2 là true, gia tri c̣ ua op1 ́ ̉ | op2 luôn luôn | op2 đươc̣ tiń h kể cả khi op1 là true ^ op1 Nếu op1 ^ op2 khác op2 Nhâṇ xé t: + Phép toán && ( & ) chỉ nhâṇ giá tri ̣true khi và chỉ khi cả hai toán haṇ g đều là true
  95. + Phép toán || ( | ) chi ̉ nhâṇ giá tri f̣ alse khi và chi ̉ khi cả hai toán haṇ g là false + Phép toán ^ chi ̉ nhâṇ giá tri ̣ true khi và chi ̉ khi hai toán haṇ g khác nhau 6. phé p toá n thao tá c trên bit 6.1. Phé p toá n dic̣h bit Ta sẽ mô tả phép toán dic̣ h chuyển qua bảng sau: Phep Sư ́ ̉ Kết qua toá n duṇ g ̉
  96. Dic̣ h chuyển op1 op1 sang phải >> >> op2 bit, op2 bit op2 phiá bên phải sẽ đươc̣ điền bằnDgi cc̣ hác bit́ 0 chuyển op1 sang trai op2 ́ op1 bit(giữ nguyên << << dấu của op1), op2 op2 bit nằm bên trái sẽ đươc̣ điền bằng
  97. các bit́ 0 >>> op1>>> op2 Dic̣ h chuyển op1 sang phải op2 bit, op2 bit Sau đây là hiǹ h minh hoa ̣ phép toán dic̣ h bit́
  98. Vi ́ du:̣ 13>>1=6 vi ̀ 13=11012 do vâỵ khi dic̣ h phả i môṭ bit ta sẽ đươc̣ 1102=6 5<<1=10 vi ̀ 5=1012 do vâỵ
  99. khi dic̣ h trái 1 bit ta sẽ đươc̣ 10102=10 5<<2=100 vi ̀ 5=1012 do vâỵ khi dic̣ h trái 2 bit ta sẽ đươc̣ 101002=100 Nhâṇ xé t: phé p toá n dic̣h trá i môṭ bit chí nh là phé p nhân vớ i 2, cò n dic̣h phả i chí nh là phép chia cho 2 6.2. Phé p toá n logic trên bit Các phép toán thao tác bit cho phép ta thao tác trên từng bit riêng lẻ trong môṭ kiểu dữ
  100. liêụ thić h hơp̣ , các phép toán thao tác bit thưc̣ hiêṇ đaị số boolean trên các bit tương ứng của 2 toán haṇ g để taọ ra kết quả Ta tóm tắt các phép toán trong bảng sau: Phép Sử Thưc̣ hiêṇ toá n duṇ g Thưc̣ hiêṇ op1 phép and các & & op2 bit tương ứng của op1 với op2
  101. Thưc̣ hiêṇ phep or cac op1 | ́ ́ | bit tương ưng op2 ́ của op1 với op2 Thưc̣ hiêṇ phep xor cac op1 ́ ́ ^ bit tương ưng ^ op2 ́ của op1 với op2 Thưc̣ hiêṇ ~ ~op2 phép lâṭ các bit của op2
  102. Bảng giá tri ̣chân lý của các phép toán đái số boolean: Phép AND op1 op2 Result 0 0 0 0 1 0 1 0 0 1 1 1 Phép OR op1 op2 Result 0 0 0 0 1 1 1 0 1
  103. 1 1 1 Phép XOR op op1 Result 2 0 0 0 0 1 1 1 0 1 1 1 0 Phép NOT op1 Result 0 1
  104. V1i ́ du:̣ 0 1101// 13 & 1100// 12 1100// 12 1101// 13 | 1100// 12 1101// 13 1101// 13 ^ 1100// 12 0001// 1
  105. ! 10101=01010 7. Toá n tử gá n tắ t Giống như C/C++ java cũng có toán tử gán, ta tóm tắt các toán tử gán qua bảng sau: Phép Sử Tương gá n duṇ g đương op1 op1 = += += op2 op1 + op2 op1 -= op1 = -= op2 op1 - op2 op1 op1 =
  106. *= *= op2 op1 * op2 op1/ = op1 = /= op2 op1/ op2 op1 op1 = %= %= op2 op1 % op2 op1 op1 = &= &= op2 op1 & op2 op1 |= op1 = |= op2 op1 | op2 op1 op1 = ^= ^= op2 op1 ^ op2 <<= op1 op1 = <<= op2 op1 << op2
  107. >>= op1 op1 = >>= op2 op1 >> op2 op1 op1 = >>>= >>>= op1 >>> op2 op2 8. Thứ tư ̣ ưu tiên củ a cá c phé p toá n Thứ tư ̣ ưu tiên của các phép toán xác điṇ h triǹ h tư ̣ tiń h toán giá tri ̣của môṭ biểu thức, java có những quy tắc riêng để xác điṇ h triǹ h tư ̣ tiń h toán của biểu thức, ta phải nhớ quy tắc sau: • các phép toán môṭ ngôi
  108. bao giờ cũng đươc̣ thưc̣ hiêṇ trước tiên • trong môṭ biểu thức có nhiều phép toán thi ̀ phép toán nào có đô ̣ưu tiên cao hơn s ẽ đươc̣ thưc̣ hiêṇ trước phép toán có đô ̣ưu tiên thấp • trong môṭ biểu thức có nhiều phép toán có đô ̣ ưu tiên ngang nhau thi ̀ chúng sẽ đươc̣ tiń h theo triǹ h tư ̣từ trái qua phải Ta có bảng tóm tắt thứ tư ̣ưu
  109. tiên của các phép toán trong bảng sau: postfix []. (params) operators expr++ expr ++expr unary expr +expr operators -expr ~! creation or new cast (type)expr multiplicative */ % additive + - shift > >>>
  110. relational = instanceof equality ==! = Bitwise & AND Bitwise ^ exclusive OR Bitwise | inclusive OR Logical && AND Logical OR || Conditional ?:
  111. = += -= *=/ Assignment = %= &= ^= |= >= Trong bảng t>rê>n> =thứ tư ̣ ưu tiên của các phép toán đươc̣ giảm từ trên xuống dưới, trên cùng môṭ hàng thi ̀ chúng có đô ̣ưu tiên ngang nhau. 1. Toán tử dâỹ Không giống như C/C++, trong java chỗ duy nhất mà ta có thể đăṭ toán tử dâỹ là bên trong căp̣ ngoăc̣ tròn của cấu trúc for( sẽ đươc̣ mô tả chi tiết
  112. trong chương sau ) IX. Toá n tử chuyể n kiể u 9.1 Chuyể n đổ i kiể u không tườ ng minh Viêc̣ chuyển đổi kiểu thường đươc̣ diễn ra môṭ cách tư ̣ đôṇ g trong trường hơp̣ biểu thức gồm nhiều toán haṇ g có kiểu dữ liêụ khác nhau. Điều này đôi khi làm cho baṇ khá ngac̣ nhiên vi ̀ nhâṇ đươc̣ môṭ kết quả không theo ý muốn. Ví
  113. du ̣ ta xét đoaṇ triǹ h sau: int two=2, three=3; float result=1.5 +three/two; kết quả nhâṇ đươc̣ của result là 2.5. Điều mà baṇ mong muốn là 3.0 chứ không phải là 2.5. Kết quả 2.5 nhâṇ đươc̣ là do three và two là hai giá tri ̣ nguyên nên kết quả của phép chia three/two cho ta môṭ giá tri ̣ nguyên bàng 1 chứ không phải là 1.5. Để nói rằng kết quả của
  114. phép chia three/two là môṭ giá tri ̣thưc̣ chứ không phải là môṭ giá tri ̣nguyên thi ̀ môṭ trong hai toán haṇ g của phép chia này phải là môṭ số thưc̣ . Do vâỵ ta cần phải chuyển kiểu của môṭ trong hai toán haṇ g này hoăc̣ cả hai thành số thưc̣ . Để nhâṇ đươc̣ kết quả đúng trong trường hơp̣ này baṇ c ầ n viết như sau: float result=1.5 + (float)three/two; hoăc̣ float result=1.5 +three/(float)two;
  115. hoăc̣ float result=1.5 + (float)three/(float)two; Lý do mà ta viết như trên là nếu trong môṭ phép toán có sư ̣ tham gia của nhiều toán haṇ g có kiểu khác nhau thi ̀ java sẽ chuyển kiểu tư ̣ đôṇ g cho các toán haṇ g môṭ cách tư ̣đôṇ g theo quy tắc sau: byte -> short -> int -> long - > float -> double 9.2. Chuyể n đổ i kiể u tườ ng minh Để chuyển đổi kiể u môṭ cách
  116. tườ ng minh ta sử duṇ g cú pháp sau: (type) biểu_thức; khi găp̣ câu lêṇ h này java sẽ tiń h toán giá tri ̣ của biểu thức sau đó chuyển đổi kiểu giá tri ̣ của biểu thức thành kiểu type. Vi ́ du:̣ (int) 2.5 * 2 = 4 (int) 2.5 * 2.5 = 5 (int)(2.5 * 2.5) = 6 1+ (float)5/2=1+5/(float)2=1+ (float)5/(float)2=3.5
  117. Chú ý: 1. Phép toán chuyển kiểu là phép toán có đô ̣ ưu tiên cao, nên (int)3.5*2¹(int)(3.4*2) 2 . Cần chú ý khi chuyển môṭ biểu thức kiểu dữ liêụ có miền giá tri ̣ lớn sang môṭ kiểu có miền giá tri ṇ hỏ hơn. Trong trường hơp̣ này có thể baṇ sẽ bi ṃ ất thông tin. X. Cá c hà m toá n hoc̣ Các hàm toán hoc̣ như sin, cos, sqrt đươc̣ java viết săñ
  118. trong lớp Math. Lớp này nằm trong gói java.lang (gói măc̣ điṇ h) do vâỵ baṇ không cần phải thêm câu lêṇ h import ở đầu chương triǹ h để có thể sử duṇ g lớp này. Các hàm này đươc̣ viết là các phương thức tiñ h do vâỵ ta không cần phải taọ ra thể hiêṇ của lớp Math. Bảng sau liêṭ kê môṭ số phương thức tiñ h trong lớp Math: Tên Mô Kiểu Kiểu phương tả ý tham
  119. thứ c nghiã số trả v arg là môṭ biểu thức tiń h kiểu sin double sin(arg) double của thể arg hiêṇ môṭ cung theo radians
  120. arg là môṭ biểu ́ tinh thức cos cos(arg) kiểu double của double arg thể hiêṇ môṭ cung theo radians
  121. m thư tiń h tang cua ́ tan(arg) ̉ double t arg h cung theo radians m tiń h sin-1 thứ asin(arg) (arcsin) double t arg h cung theo radians
  122. tiń h m cos-1 acos(arg) thứ (arccosin) của double t arg h cung theo radians m tiń h thứ atan(arg) tan-1 (arctang) double t của arg h cung theo radians
  123. la ̀ tiń h biểu atan2 tan-1 (arctang) thức (arg1,arg2) của double arg1/arg2 th mô ̣ cung radians m t iń h tri ̣ tuyêṭ abs(arg) thư đối cua arg ́ ̉ long, float, hoăc̣ double
  124. max Nhâṇ về giá (arg1,arg2) tri ḷ ớn là trong hai tham số double
  125. N hâṇ về gia biùu min ́ tri ṇ ho trong hait (arg1,arg2) ̉ tham số kiùu long, double Nhâṇ về giá tri nguyên nho ceil(arg) ̣ ̉ hơn hoăc̣ bằngk arg
  126. double Nhâṇ về giá tri nguyên floor(arg) ̣ lớn hơn hoăc̣ k bằng arg double Trả về giá
  127. tri ̣ nguyên gần arg nhất, round(arg) giá tri ̣ này chiń h là giá triḳ của arg sau khi đa ̃ làm tròn double Giống rint(arg) như round(arg) k
  128. d ouble t iń h căn bâc sqrt(arg) ̣ hai của arg k double C và pow la cac tiń h arg1arg2 ̀ ́ (arg1,arg2)
  129. double arg là biểu tiń h exp(arg) thưc earg ́ kiểu double tiń h arg logarithmớ là biểu log(arg) số thức e của kiểu arg double N hâṇ về môṭ số giả
  130. ngâũ Không random() nhiên có tham nằm số trong khoản [0, 1) Vi ́ du ̣ về các hàm toán hoc̣ trong lớp Math, baṇ hãy gõ đoaṇ chương triǹ h sau và cho chaỵ thử để thấy đươc̣ kết quả tiń h toán của các hàm toán hoc̣ . XI. Cá c phé p toá n trên kiể u kí tư ̣
  131. Đối với kiểu ki ́ tư ̣ ta có thể thưc̣ hiêṇ các phép toán số hoc̣ (như: +, -, *,/ ) và các phép toán quan hê.̣ Vi ́ du:̣ char kt1=’A’; char kt2=tk1+a;// kt2 nhâṇ ký tư ̣B char kt3=(char)33*2;// kt3 nhâṇ ký tư ̣B (kt1>kt2)= false; (kt2=kt3)= false; BÀ I 3 ĐIỀ U KHIỂ N LUỒ NG CHƯƠNG TRÌNH
  132. Chương triǹ h là môṭ dâỹ các lêṇ h đươc̣ bố tri ́ thưc̣ hiêṇ theo môṭ triǹ h tư ̣ nào đó, nhưng đôi khi ta muốn điều khiển luồng thưc̣ hiêṇ của chương triǹ h tuỳ thuôc̣ vào điều kiêṇ gì đó. Ngôn ngữ lâp̣ triǹ h java cung cấp môṭ số phát biểu cho phép t a điều khiển luồng thưc̣ hiêṇ của chương triǹ h, chúng đươc̣ liêṭ kê trong bảng sau: Kiểu Tư khoa lêṇ h ̀ ́
  133. Lăp̣ while, do-while, for Quyết if-else, switch- điṇ h case Xử lý try-catch-finally, lỗi throw Rẽ break, continue, nhánh label:, return I. cấ u trú c rẽ nhá nh 1.1. phá t biể u if a) daṇ g khuyế t Cú pháp if(Boolean-expression) statement;
  134. sư ̣ hoaṭ đôṇ g của cấu trúc if thiếu đươc̣ mô ta qua sơ đồ sau: b) daṇ g đủ Cú pháp if(Boolean-expression) statement1; else statement2; sư ̣ hoaṭ đôṇ g của cấu trúc if thiếu đươc̣ mô ta qua sơ đồ sau: 1.2. biể u thứ c điều kiêṇ Cú pháp:
  135. Variable=booleanExpression? true-result-expression: false-result-expression; 1.3. cấ u trú c switch a) Daṇ g khuyế t Cú pháp switch(biểu_thức) { case gt_1: lêṇ h 1; [ break;] case gt_2: lêṇ h 2; [ break;] case gt_n: lêṇ h n; [ break;]
  136. } Sau đây là sơ đồ khối mô tả sư ̣ hoaṭ đôṇ g của cấu trúc rẽ nhánh switch daṇ g thiếu b) Daṇ g đủ Cú pháp switch(biểu_thức) { case gt_1: lêṇ h 1; [ break;] case gt_2: lêṇ h 2; [ break;] case gt_n: lêṇ h n; [ break;] default:
  137. lêṇ h n+1; } Sau đây là sơ đồ khối mô tả sư ̣ hoaṭ đôṇ g của cấu trúc switch daṇ g đủ Chú ý : - biểu_thức phải là môṭ biểu thức có kiểu char, byte, short, int nhưng không thể là kiểu long, nếu biểu_thức có kiểu khác với các kiểu liêṭ kê ở trên thi ̀ java sẽ đưa ra môṭ thông báo lỗi. - Nếu biểu_thức bằng giá tri ̣
  138. của gt_i thi ̀ các lêṇ h từ lêṇ h i cho đế n lêṇ h n nếu không có default (lêṇ h n+1 nếu có default) sẽ đươc̣ thưc̣ hiêṇ . - Câu lêṇ h break thoát ra khỏi cấu trúc switch. S ơ đồ khối mô tả sư ̣ hoaṭ đôṇ g của cấu trúc switch trong trường hơp̣ có lêṇ h break 1.4 Toá n tử điều kiêṇ Toán tử điều kiêṇ là môṭ loaị toán tử đăc̣ biêṭ vi ̀ nó gồm ba thành phần cấu thành biểu
  139. thức điề u kiêṇ . hay nói cách khác toán tử điều kiêṇ là toán tử 3 ngôi. Cú phá p : biể u thứ c 1? biể u thứ c 2 : biể u thứ c 3; Trong đó biểu thứ c 1: Biểu thức 1 là môṭ biểu thức logic. Tức là nó trả trả về giá tri Ṭ rue hoăc̣ False biểu thứ c 2: Giá tri ̣ trả về nếu biểu thức 1 nhâṇ giá True. biểu thứ c 3: Giá tri ̣ trả về nếu biểu thức 1 nhâṇ giá tri ̣
  140. False Chú ý : Kiểu giá tri ̣của biểu thức 2 và biểu thức 3 phải tương thić h với nhau. Vi ́ du:̣ Đoaṇ biểu thức điều kiêṇ sau trả về giá tri ̣“a là số chăñ ” nếu như giá tri c̣ ủa biến a là số chăñ , ngươc̣ laị trả về giá tri ̣ “a là số lẻ” nế u như giá tri ̣ của biến a là số lẻ. String result=a%2==0 ? “a là số chẵn” : “a là số lẻ ”; II. Cấ u trú c lăp̣ while và do-
  141. while 1. Lăp̣ kiể m tra điều kiêṇ trướ c Ta có thể sử duṇ g cấu trúc while để thưc̣ thi lăp̣ đi lăp̣ laị môṭ lêṇ h hoăc̣ môṭ khối lêṇ h trong khi điều kiêṇ đúng Cú pháp: while (BooleanExpression) { statement; } ta có thể thấy đươc̣ luồng
  142. thưc̣ hiêṇ của chương triǹ h thông qua sơ đồ khối sau: trước tiên phát biểu while sẽ tiń h giá tri ̣của biểu thức logic, nếu giá tri c̣ ủa biểu thức logic là đúng thi ̀ câu lêṇ h trong thân của while sẽ đươc̣ thưc̣ hiêṇ , sau khi thưc̣ hiêṇ xong nó tiń h laị giá tri ̣ của biểu thức logic, nếu giá tri đ̣ úng nó laị tiếp tuc̣ thưc̣ hiêṇ lêṇ h trong thân while cho đến khi giá tri ̣ của biểu thức sai. Vi ́ du:̣ public class WhileDemo {
  143. public static void main(String[] args) { String copyFromMe = "Copy this string until you " + "encounter the letter 'g'."; StringBuffer copyToMe = new StringBuffer(); int i = 0; char c = copyFromMe.charAt(i); while (c! = 'g') { copyToMe.append(c); c = copyFromMe.charAt(++i);
  144. } System.out.println(copyToMe); } } Chú ý : + biểu thức bên trong căp̣ ngoăc̣ tròn phải là môṭ biểu thức logic ( biểu thức trả về giá tri ṭ rue hoăc̣ false ) + biểu thức điề u kiêṇ phải nằm trong căp̣ ngoăc̣ tròn + sau từ khoá while ta chi ̉ có thể đăṭ đươc̣ duy nhất môṭ lêṇ h,
  145. do vâỵ để c ó thể thưc̣ hiêṇ nhiều tác vu ̣ sau while ta phải bao chúng trong môṭ khối lêṇ h + bên trong thân của vòng lăp̣ while ta nên có lêṇ h làm thay đổi giá tri ̣của biểu thức logic, nếu không chúng ta sẽ rơi vào vòng lăp̣ vô haṇ . + câu lêṇ h trong thân cấu trúc while có thể không đươc̣ thưc̣ hiêṇ lần nào (do biểu thức lôgic ban đầu có giá tri f̣ alse ) 2. Lăp̣ kiể m tra điều kiêṇ
  146. sau Cú pháp: do { statement(s); } while (expression); sư ̣ hoaṭ đôṇ g của cấu trúc này đươc̣ thể hiêṇ qua sơ đồ sau: Nhiǹ vào sơ đồ này ta thấy sư ̣hoaṭ đôṇ g của nó như sau: b1) thưc̣ hiêṇ lêṇ h b2) sau khi thưc̣ hiêṇ lêṇ h xong nó tiń h giá tri ̣ của biểu thức logic b3) nếu biểu thức logic đúng nó quay trở laị b1,
  147. nếu sai thi ̀ b4 b4) kết thúc vòng lăp̣ và thưc̣ hiêṇ lêṇ h sau do-while vi ́ du:̣ public class DoWhileDemo { public static void main(String[] args) { String copyFromMe = "Copy this string until you " + "encounter the letter 'g'."; StringBuffer copyToMe = new StringBuffer(); int i = 0; char c =
  148. copyFromMe.charAt(i); do { copyToMe.append(c); c = copyFromMe.charAt(++i); } while (c! = 'g'); System.out.println(copyToMe); } } Chú ý: + biểu thức bên trong căp̣ ngoăc̣ tròn phải là môṭ biểu thức logic ( biểu thức trả về giá tri ṭ rue hoăc̣ false )
  149. + biểu thức điề u kiêṇ phải nằm trong căp̣ ngoăc̣ tròn + sau từ khoá do ta có thể đăṭ đươc̣ nhiều lêṇ h + bên trong thân của vòng lăp̣ do-while ta nên có lêṇ h làm thay đổi giá tri ̣ của biểu thức logic, nếu không chúng ta sẽ rơi vào vòng lăp̣ vô haṇ . + câu lêṇ h trong thân cấu trúc do-while đươc̣ thưc̣ hiêṇ it́ nhất môṭ lần III. Cấ u trú c for
  150. đây la cấu trúc lăp̣ phổ biến nhất trong các ngôn ngữ lâp̣ triǹ h, mà nôị dung cuả vòng lăp̣ cần phải lăp̣ đi lăp̣ la ị môṭ số lần biết trước, cú pháp của nó như sau: for (initialization; termination; increment) { statement } Trong đó: - initialization là giá tri ̣ khở i taọ trướ c khi vò ng lăp̣ bắ t
  151. đầ u, nó chỉ đươc̣ thưc̣ hiêṇ duy nhất môṭ lân trước khi vòng lăp̣ bắt đầu - termination là đi ề u kiêṇ dù ng để kế t thú c quá trì nh lăp̣ - increment là câu lêṇ h dù ng để điề u khiể n quá trì nh lăp̣ - statement là câu lêṇ h mà ta cầ n phả i thưc̣ hiêṇ lăp̣ đi lăp̣ laị. Sơ đồ khối diễn giả i sư ̣ hoaṭ đôṇ g của cấu trúc for sau: Nhâṇ xé t:
  152. + thân của cấu trúc lăp̣ for ta chi ̉ có thể đăṭ đươc̣ duy nhất môṭ lêṇ h, do vâỵ để có thể thưc̣ hiêṇ nhiều tác vu ̣ trong thân for ta phải bao chúng trong khối lêṇ h + thân vòng lăp̣ for có thể không đươc̣ thưc̣ hiêṇ lần nào + c á c phầ n initialization, termination, increment có thể khuyết tuy nhiên dấy phẩy dành cho nó vâñ phải có + số lần thưc̣ hiêṇ initialization=1
  153. + số lần thưc̣ hiêṇ termination = số lần lăp̣ +1 + số lần thưc̣ hiêṇ increment = số lần lăp̣ + ta có thể đăṭ môṭ vài khai báo biến trong phần initialization, như vi ́ du ̣sau + ta có thể mô tả cấu trúc while thông qua cấu trúc for như sau for(; Boolean_Expression;) statement; Vi ́ du:̣ kiêṭ kê ra 128 các ki ́ tư ̣ asciii đầu tiên public class
  154. ListCharacters { public static void main(String[] args) { for( char c = 0; c < 128; c++) if (c! = 26 )// ANSI Clear screen System.out.println( "value: " + (int)c + " character: " + c); } }// /:~ Toá n tử dẫy và vò ng lăp̣ for Trong bài trước ta đa ̃ nhắc
  155. đến toán tử dâỹ (toán tử dâỹ là môṭ dâỹ các lêṇ h đơn đươc̣ cách nhau bởi dấu phẩy), trong java chỗ duy nhất mà ta có thể đăṭ toán tử dẫ y đó l à bên trong cấu trúc lăp̣ for, ta có thể đă ̣t toá n tử dâỹ cả trong phần initialization lâñ phần increment Vi ́ du ̣về toán tử dâỹ public class CommaOperator { public static void main(String[] args) {
  156. for(int i = 1, j = i + 10; i < 5; i++, j = i * 2) { System.out.println("i= " + i + " j= " + j); } } } Kết quả chaỵ chương triǹ h sau: i= 1 j= 11 i= 2 j= 4 i= 3 j= 6 i= 4 j= 8 IV. Lêṇ h break và continue Bên trong thân của các cấu trúc lăp̣ ta có thể điều khiển
  157. luồng thưc̣ hiêṇ bằng cách sử duṇ g lêṇ h break và continue, lêṇ h break sẽ chấm dứt quá triǹ h lăp̣ mà không thưc̣ hiêṇ nốt phân còn laị của cấu trúc lăp̣ , continue sẽ ngưng thưc̣ thi phần còn laị của thân vòng lăp̣ và chuyển điều khiển về điểm bắt đầu của vòng lăp̣ , để thưc̣ hiêṇ lần lăp̣ tiếp theo, vi ́ du ̣ sau chi ̉ ra cách sử duṇ g break và continue bên trong cấu trúc lăp̣ for và while
  158. public class BreakAndContinue { public static void main(String[] args) { for(int i = 0; i < 100; i++) { if(i == 74) break;// Out of for loop if(i % 9! = 0) continue;// Next iteration System.out.println(i); } int i = 0; // An "infinite loop": while(true) {
  159. i++; int j = i * 27; if(j == 1269) break;// Out of loop if(i % 10! = 0) continue;// Top of loop System.out.println(i); } } } kết quả chaỵ chương triǹ h sau: 0 9
  160. 18 27 36 45 54 63 72 10 20 30 40 Bên trong cấu trúc lăp̣ for
  161. giá tri c̣ ủa i không thể đaṭ đươc̣ giá tri 1̣ 00 vi ̀ phát biểu break sẽ kết thúc vòng lăp̣ khi i=74 Chú ý : Java không có lêṇ h nhẩ y goto, tuy nhiên trong java vẫn có môṭ và i vế t tí ch của lêṇ h nhẩy goto ( khét tiếng và đươc̣ coi là nguồn sinh các lỗi ) đó là lêṇ h break và continue Nhãn củ a vò ng lăp̣ Trong thưc̣ tế các vòng lăp̣ có thể lồng vào nhau, mức đô ̣ lồng nhau không haṇ chế, thế
  162. thi ̀ câu hỏi đăṭ ra là lêṇ h break sẽ thoát ra khỏi vòng lăp̣ nào, câu trả lời là nó thoát ra khỏi vòng lăp̣ mà lêṇ h break đươc̣ đăṭ, thế thi ̀ làm cách nào ta có thể cho nó thoát ra khỏi môṭ vòng lăp̣ tuỳ ý nào đó, câu trả lời là java đã hỗ trơ ̣ cho ta môṭ công cu ̣đó là nhãn của vòng lăp̣ . Nhañ là môṭ cái tên sau đó có 2 dấu chấm Vi ́ du ̣LabelName: Chỗ duy nhất mà nhãn có ý
  163. nghiã đó là ngay trước lêṇ h lăp̣ , ta không thể có bất cứ môṭ lêṇ h nào nằm giữa nhãn và lêṇ h lăp̣ , ta mô tả sư ̣ hoaṭ đôṇ g, cách sử duṇ g nhañ của vòng lăp̣ thông qua vi ́ du ̣sau: public class LabeledFor { public static vo id (String[] args) { int i = 0; outer:// Can't have statements here for(; true; ) {// infinite loop inner:// Can't have statements
  164. here for(; i < 10; i++) { prt("i = " + i); if(i == 2) { prt("continue"); continue; } if(i == 3) { prt("break"); i++;// Otherwise i never // gets incremented. break; } if(i == 7) { prt("continue outer"); i++;// Otherwise i never // gets incremented. continue outer;
  165. } if(i == 8) { prt("break outer"); break outer; } for(int k = 0; k < 5; k++) { if(k == 3) { prt("continue inner"); continue inner; } } } }
  166. // Can't break or continue // to labels here } static void prt(String s) { System.out.println(s); } } kết quả chaỵ chương triǹ h như sau: i = 0 continue inner i = 1 continue inner i = 2 continue i = 3 break i = 4
  167. continue inner i = 5 continue inner i = 6 continue inner i = 7 continue outer i = 8 break outer Chương 2 LÂP̣ TRIǸ H HƯỚ NG ĐỐ I TƯƠṆ G Lớp là khái niêṃ troṇ g tâm của lâp̣ triǹ h hướng đối tươṇ g, java là ngôn ngữ lâp̣ triǹ h hướng đối tươṇ g,
  168. môṭ chương triǹ h java gồm môṭ tâp̣ các đối tươṇ g, c á c đối tươṇ g này phối hơp̣ với nhau để taọ thành môṭ ứng duṇ g hoàn chin̉ h. Các đối tươṇ g đươc̣ mô tả qua khái niêṃ lớp, lớp là sư ̣ mở rôṇ g khái niêṃ RECORD trong pascal, hay struct của C, ngoài các thành phần dữ liêụ , lớp còn có các hàm ( phương thức, hành vi ), ta có thể xem lớp là môṭ kiểu dữ liêụ , vi ̀ vâỵ người ta cò n goị lớp là kiểu dữ liêụ đối tươṇ g. Sau khi
  169. điṇ h nghiã lớp ta có thể taọ ra các đối tươṇ g ( bằng cách khai báo biến ) của lớp vừa taọ , do vâỵ có thể quan niêṃ lớp là tâp̣ hơp̣ các đối tươṇ g cùng kiểu. BÀI 1 ĐIṆ H NGHIÃ LỚ P I. Khai bá o lớ p 1.1. Môṭ lớp đươc̣ điṇ h nghiã theo mâũ sau: [pbulic][final][abstract] class { // khai bá o cá c thuôc̣ tí nh
  170. // khai bá o cá c phương thứ c } sau đâu là vi ́ du ̣ đơn giản điṇ h nghiã lớp ngăn xếp:
  171. Tổng quá t: môṭ lớp đươc̣ khai bá o daṇ g sau: [public][ ][ class [extends ] [implements ] { } Trong đó : 1) bởi măc̣ điṇ h môṭ lớp chi ̉ có
  172. thể sử duṇ g bởi môṭ lớp khác trong cùng môṭ gó i với lớp đó, nếu muốn gói khác có thể sử duṇ g lớp này thi ̀ lớp này phải đươc̣ khai báo là lớp public. 2) abstract là bổ từ cho java biết đây là môṭ lớp trừu tươṇ g, do vâỵ ta không thể taọ ra môṭ thể hiêṇ của lớp này 3) final là bổ từ cho java biế t đây là môṭ lớp không thể kế thừa
  173. 4) class là từ khoá cho chương triǹ h biết ta đang khai báo môṭ lớp, lớp này có tên là NameOfClass 5) extends là từ khoá cho java biết lớp này này đươc̣ kế thừa từ lớp super 6) implements là từ khoá cho java biết lớp này sẽ triển khai giao diêṇ Interfaces, đây là môṭ daṇ g tương tư ̣ như kế thừa bôị của java. Chú ý : 1) Thuôc̣ tiń h của lớp là môṭ
  174. biến có kiểu dữ liêụ bất kỳ, nó có thể laị là môṭ biến có kiểu là chiń h lớp đó 2 ) Khi khai báo các thành phần của lớp (thuôc̣ tiń h và phương thức) có thể dùng môṭ trong các từ khoá private, public, protected để giứo haṇ sư ̣ truy câp̣ đến thành phần đó. – các thành phần private chỉ có thể sử duṇ g đươc̣ ở bên
  175. trong lớp, ta không thể truy câp̣ vào các thành phần private từ bên ngoài lớp – Các thành phần public có thể truy câp̣ đươc̣ cả bên trong lớp lâñ bên ngoài lớp. – các thành phần protected tương tư ̣ như các thành phần private, nhưng có thể truy câp̣ đươc̣ từ bất cứ lớp con nào kế thừa từ nó.
  176. – Nếu môṭ thành phần của lớp khi khai báo mà không sử duṇ g môṭ trong 3 bổ từ protected, private, public thi ̀ sư ̣ truy câp̣ là baṇ bè, tức là thành phần này có thể truy câp̣ đươc̣ từ bất cứ lớp nào trong cùng gói với lớp đó. 3) Các thuôc̣ tiń h nên để mức truy câp̣ private để đảm bảo tiń h dấu kiń và lúc đó để bên ngoài phaṃ vi của lớp có thể truy câp̣ đươc̣ đến thành phần private này
  177. ta phải taọ ra các phương thức phương thức get và set. 4 ) Các phương thức thường khai báo là public, để chúng có thể truy câp̣ từ bất cứ đâu. 5) Trong môṭ têp̣ chương triǹ h (hay còn goị là môṭ đơn vi ̣ biên dic̣ h) chỉ có môṭ lớp đươc̣ khai báo là public, và tên lớp public này phải trùng với tên của têp̣ kể cả chữ hoa, chữ thường - Khai bá o thuôc̣ tí nh Trở laị lớp Stack
  178. public class Stack { private Vector items; // a method with same name as a member variable public Vector items() { } } Trong lớp Stack trên ta có môṭ thuôc̣ tiń h đươc̣ điṇ h nghiã như sau: private Vector items; Viêc̣ khai báo như trên đươc̣ goị là khai báo thuôc̣ tiń h hay
  179. còn goị là biến thành viên lớp Tổng quát viêc̣ khai báo môṭ thuôc̣ tiń h đươc̣ viết theo mâũ sau: Trong đó: • accessLevel có thể là môṭ trong cá c từ public, private, protected hoăc̣ có thể bỏ trống, ý nghiã của các bổ từ
  180. này đươc̣ mô tả ở phần trên • - static là từ khoá bá o rằ ng đây là môṭ thuôc̣ tí nh lớ p, nó là môṭ thuôc̣ tí nh sử duṇ g chung cho cả lớp, nó không là của riêng môṭ đối tươṇ g nào. transient va volatile • - ̀ chưa đươc̣ dù ng type la môt kiể u dư • - ̀ ̣ ̃ liêụ nà o đó · name là tên củ a thuôc̣ tí nh
  181. Chú ý : Ta phải phân biêṭ đươc̣ viêc̣ khai báo như thế nào là khai báo thuôc̣ tiń h, khai báo thế nào là khai báo biến thông thường? Câu trả lời là tất cả các khai báo bên trong thân của môṭ lớp và bên ngoài tất cả các phương thức và hàm taọ thi ̀ đó là khai báo thuôc̣ tiń h, khai báo ở những chỗ khác sẽ cho ta biến. - Khai bá o phương thứ c Trong lớp Stack trên ta có phương thức push dùng để đẩy
  182. môṭ đối tươṇ g vào đỉ n h ngăn xếp, nó đươc̣ điṇ h nghiã như sau: Cũng giống như môṭ lớp, môṭ phương thức cũng gồm có 2 phần: phần khai báo và phầ n thân - Phần khai báo gồm có những phần sau( chi tiết của khai báo đươc̣ mô tả sau):
  183. - Phần thân của phương thức gồm các lêṇ h để mô tả hành vi của phương thức, các hành vi này đươc̣ viết bằng các lêṇ h của java. II. Chi tiế t về khai bá o môṭ phương thứ c 1. Tổ ng quá t môṭ phương thứ c đươc̣ khai bá o như sau: accessLevel //mô tả mức đô ̣ truy câp̣ đến phương thức
  184. static //đây là phương thức lớp abstract //đây là phương thức không có cài đăṭ final //phương thức này không thể ghi đè native //phương thức này đươc̣ viết trong môṭ ngôn ngữ khác synchronized //đây là phương thức đồng bô ̣ returnType //giá tri ̣trả về của phương thức MethodName //tên của phương thức
  185. throws exception //khai báo các ngoaị lê ̣ có thể đươc̣ nem ra từ phương thức Trong đó: - accessLevel có thể là môṭ trong các từ khoá public, private, protected hoăc̣ bỏ trống, ý nghiã của các bổ từ này đươc̣ mô tả trong phần khai báo lớp - static là từ khoá báo cho
  186. java biế t đây là môṭ phương thức lớp - abstract từ khoá cho biết đây là môṭ lớp trừu tươṇ g, nó không có cài đăṭ. - final đây là từ khoá báo cho java biết đây là phương thức không thể ghi đè từ lớp con - native đây là t ừ khoá bá o cho java biế t phương thức nà y đươc̣ viế t bằng môṭ ngôn ngữ lâp̣ triǹ h nào đó
  187. không phải là java ( thường đươc̣ viết bằng C/C++) - synchronized đây là môṭ phương thức đồng bô,̣ nó rất hữu ić h khi nhiều phươn g thức cùng truy câp̣ đồng thời vào tài nguyên miền găng - returnType là môṭ kiểu dữ liêụ , đây là kiểu trả về của phương thức, khi phương thức không trả về dữ liêụ thi ̀ phải dùng từ khoá void - MethodName là tên của phương thức, tên của phương
  188. thức đươc̣ đăṭ theo quy tắc đăṭ tên của java - throws là từ khoá dùng để khai báo các ngoaị lê ̣ có thể đươc̣ ném ra từ phươn g thức, theo sau từ khoá này là danh sách các ngoaị lê ̣ có thể đươc̣ phương thức này ném ra Chú ý : 1 ) Nếu trong lớp có it́ nhất môṭ phương thức trừu tươṇ g thì lớp đó phải là lớp trừu tươṇ g 2) không có thuôc̣ tiń h trừu tươṇ g
  189. 3) ta không thể taọ đối tươṇ g của lớp trừu tươṇ g 4) khác với ngôn ngữ C/C++, java bắt buôc̣ baṇ phải khai báo giá tri ̣trả về cho phương thức, nế u phương thức không trả về dữ liêụ thi dùng từ khoá void (trong C/C++ khi ta không khai báo giá tri ̣ trả về thi ̀ măc̣ điṇ h giá tri ṭ rả về là int) 2. Nhâṇ giá tri ̣ trả về từ phương thứ c Ta khai báo kiểu giá tri ̣trả về từ lúc ta khai báo phương
  190. thức, bên trong thân của phương thức ta phải sử duṇ g phát biểu return value; để nhâṇ về kết quả , nế u h à m đươc̣ khai báo kiểu void thi ̀ ta chỉ s ử duṇ g phát biểu return; mêṇ h đ ề return đôi khi còn đươc̣ dùng để kết thúc môṭ phương thức. 3. Truyền th a m số cho phương thứ c Khi ta viết các phương thức, môṭ số phương thức yêu
  191. cầu phải có môṭ số tham số, c á c tham số của môṭ phương thức đươc̣ khai báo trong lời khai báo phương thức, chúng phải đươc̣ khai báo chi tiết có bao nhiêu tham số, mỗi tham số cần phải cung cấp cho chúng môṭ cái tên và kiểu dữ liêụ của chúng. Vi ́ du:̣ ta có môṭ phương thức dùng để tiń h tổng của hai số, phương thức này đươc̣ khai báo như sau: p u b l i c double
  192. tongHaiSo(double a, double b){ return (a + b); } 1. Kiể u tham số Trong java ta có thể truyền vào phương thức môṭ tham số có kiểu bất kỳ, từ kiểu dữ liêụ nguyên thuỷ cho đến tham chiếu đối tươṇ g. 2. Tên tham số Khi baṇ khai báo môṭ tham số để truyền vào phương thức thi ̀ baṇ phải cung cấp cho nó môṭ cái tên, tên nay đươc̣ sử
  193. duṇ g bên trong thân của phương thức để tham chiếu đến tham số đươc̣ truyền vào. Chú ý : tên của tham số có thể trùng với tên của thuôc̣ tiń h, khi đó tên của tham số sẽ “che” đi tên của phương thức, bởi vâỵ bên trong thân của phương thức mà có tham số có tên trùng với tên của thuôc̣ tiń h, thi ̀ khi nhắc đến cái tên đó có nghiã là nhắc đến tham số. 3. Truyền tham số theo tri ̣ K h i goị môṭ phương
  194. thức m à tham số của phương thức có kiểu nguyên thuỷ, thi ̀ bản sao giá tri ̣ của tham số thưc̣ sư ̣ sẽ đươc̣ chuyển đến phương thức, đây là đăc̣ tiń h truyền theo tri ̣ ( pass- by – value ), nghiã là phương thức không thể thay đổi giá tri c̣ ủa các tham số truyền vào. Ta kiểm tra điều này qua vi ́ du ̣sau: public class TestPassByValue {
  195. public static void test(int t) { t++; System.out.println("Gia tri của t bi?n trong ham sau khi tang len 1 la " + t); } public static void main(String[] args) { int t = 10; System.out.println("Gia tri của t tru?c khi goị ham = " + t); test(t); System.out.println("Gia tri của t truoc khi goị ham = " + t);
  196. } } ta se nhâṇ đươc̣ kết quả ra như sau: Gia tri của t truoc khi goị ham = 10 Gia tri của t bên trong ham sau khi tang len 1 la 11 Gia tri của t truoc khi goị ham = 10 4. Thân củ a phương thứ c Trong vi ́ du ̣ sau thân của phương thức isEmpty và phương thức pop đươc̣ in đâṃ và có mầu đỏ
  197. class Stack { static final int STACK_EMPTY = -1; Object[] stackelements; int topelement = STACK_EMPTY; boolean isEmpty() { if (topelement == STACK_EMPTY) return true; else return false;
  198. } Object pop() { if (topelement == STACK_EMPTY) return null; else { return stackelements[topelement ]; } } III. Từ khoá this Thông thường bên trong thân của môṭ phương thức ta c ó thể tham chiế u đến các
  199. thuôc̣ tiń h của đối tươṇ g đó, tuy nhiên trong môṭ số tiǹ h huống đăc̣ biêṭ như tên của tham số trùng với tên của thuôc̣ tiń h, lúc đó để chi ̉ các thành viên của đối tươṇ g đó ta dùng từ khoá this, từ khoá this dùng để chi ̉ đối tươṇ g này. Vi ́ du ̣ sau chi ̉ ra cho ta thấy trong tiǹ h huống này bắt buôc̣ phải dùng từ khoá this vi ̀ tên tham số của phương thức taọ dưṇ g laị trùng với tên của thuôc̣ tiń h
  200. class HSBColor { int hue, saturation, brightness; HSBColor (int hue, int saturation, int brightness) { this.hue = hue; this.saturation = saturation; this.brightness = brightness; } IV. Từ khoá super Khi môṭ lớp đươc̣ kế thừa từ lớp cha trong cả lớp cha và lớp con đều có môṭ phương
  201. thức trùng tên nhau, thế thi ̀ làm thế nào có thể goị phương thức trùng tên đó của lớp cha, java cung cấp cho ta từ khoá super dù ng để chỉ đố i tươṇ g củ a lớ p cha Ta xét vi ́ du ̣sau c lass ASillyClass { boolean aVariable; void aMethod() { aVariable = true; } } class ASillierClass extends ASillyClass {
  202. boolean aVariable; v oid aMethod() { aVariable = false; super.aMethod(); System.out.println(aVariable); System.out.println(super.aVariable); } } trong vi ́ du ̣trên ta thấy trong lớp cha có phương thức tên là aMethod trong lớp con cũng có môṭ phương thức cùng tên, ta còn thấy cả hai lớp này cùng có môṭ thuôc̣ tiń h tên aVariable để có thể truy câp̣ vào các thành
  203. viên của lớp cha ta phải dùng từ khoá super. Chú ý : ta không thể dù ng nhiề u từ khoá nà y để chỉ lớ p ông, lớ p cu ̣ chẳ ng haṇ viết như sau là sai: super.super.add(1,4); V. Sử duṇ g lớ p Sau khi khao môṭ môṭ lớp ta có thể xem lớp như là môṭ kiểu dữ liêụ , nên ta có thể taọ ra các biến, mảng các đối tươṇ g, viêc̣ khai báo môṭ
  204. biến, mảng các đối tươṇ g cũng tương tư ̣như khai báo môṭ biến, mảng của kiểu dữ liêụ nguyên thuỷ Viêc̣ khai báo môṭ biến, mảng đươc̣ khai báo theo mâũ sau: Tên_Lớ p tên_biế n; Tên_Lớ p tên_mang[kí ch t h ư ớ c mả ng]; Tên_Lớ p[kí ch thướ c mả ng] tên_mang; Về bản chất mỗi đối tươṇ g trong java là môṭ con trỏ tới môṭ vùng nhớ, vùng nhớ này chiń h
  205. là vùng nhớ dùng để lưu trữ các thuôc̣ tiń h, vùng nhớ dành cho con trỏ này thi ̀ đươc̣ cấp phát trên stack, còn vùng nhớ dành cho các thuôc̣ tiń h của đối tươṇ g này thi ̀ đươc̣ cấp phát trên heap. VI. Điều khiể n viêc̣ truy câp̣ đế n cá c thà nh viên củ a môṭ lớ p Khi xây dưṇ g môṭ lớp ta có thể haṇ chế sư ̣truy câp̣ đến các thành viên của lớp, từ môṭ đối tươṇ g khác.
  206. Ta tóm tắt qua bảng sau: Truy Truy câp̣ câp̣ câp̣ trong Tư khoa trong ̀ ́ lơp con lơp con chiń h ́ ́ cùng khác lớp đó gói gói private X - protected X X public X X default X X - X
  207. Trong bảng trên thi ̀ X thể hiêṇ cho sư ̣ truy câp̣ hơp̣ lê ̣còn – thể hiêṇ không thể truy câp̣ vào thành phần này. 1. Cá c thà nh phầ n private Các thành viên private chi ̉ có thể sử duṇ g bên trong lớp, ta không thể truy câp̣ các thành viên private từ bên ngoài lớp này. Vi ́ du ̣ class Alpha { private int iamprivate;
  208. private void privateMethod() { System.out.println("privateMethod"); } } class Beta { void accessMethod() { Alpha a = new Alpha(); a.iamprivate = 10;// không hơp̣ lê ̣ a.privateMethod();// không hơp̣ lê ̣ } }
  209. 2 . Cá c thà nh phầ n protected Các thành viên protected sẽ đươc̣ thảo luâṇ trong chương sau 3. Cá c thà nh phầ n public Các thành viên public có thể truy câp̣ từ bất cứ đâu, ta se xem vi ́ du ̣sau: package Greek; public class Alpha { public int iampublic; public void publicMethod() {
  210. System.out.println("publicMethod"); } } package Roman; import Greek.*; class Beta { void accessMethod() { Alpha a = new Alpha(); a.iampublic = 10;// hơp̣ lê ̣ a.publicMethod();// hơp̣ lê ̣ } } 4. Cá c thà nh phầ n có mứ c truy xuấ t gó i khi ta khai báo các thành
  211. viên mà không sử duṇ g môṭ trong các từ public, private, protected thi ̀ java mă ̣ c điṇ h thành viên đó có mức truy câp̣ gói. Vi ́ du ̣ package Greek; class Alpha { int iampackage; void packageMethod() { System.out.println("packageMethod"); } }
  212. package Greek; class Beta { void accessMethod() { Alpha a = new Alpha(); a.iampackage = 10;// legal a.packageMethod();// legal } } BÀ I 2 KHỞ I ĐẦ U VÀ DOṆ DEP̣ I. Phương thứ c taọ dưṇ g (constructor) 1. Công duṇ g
  213. Phương thức taọ dưṇ g là môṭ phương thứ c của lớp ( nhưng khá đăc̣ biêṭ ) thường dùng để khởi taọ môṭ đối tươṇ g mới. Thông thường người ta thường sử duṇ g hàm taọ để khởi gán giá tri ̣ cho các thuôc̣ tiń h của đối tươṇ g và có thể thưc̣ hiêṇ môṭ số công viêc̣ cần thiết khác nhằm chuẩn bi ̣ cho đối tươṇ g mới. 2. cá ch viết hàm taọ a ) đăc̣ điểm củ a phương thứ c taọ dưṇ g
  214. • hàm taọ có tên trùng với tên của lớp • hàm taọ không bao giờ trả về kết quả • nó đươc̣ java goị tư ̣đôṇ g khi môṭ đối tươṇ g của lớp đươc̣ taọ ra • hàm taọ có thể có đối số như các phương thức thông thường khác • trong môṭ lớp có thể có nhiều hàm taọ b) ví du ̣ vi ́ du ̣ 1: sử duṇ g hàm taọ để
  215. in ra màn hiǹ h xâu “Creating Rock” class Rock { Rock() {// This is the constructor System.out.println("Creating Rock"); } } public class SimpleConstructor { public static void main(String[] args) { for(int i = 0; i < 10; i++)
  216. new Rock();// call constructor } } vi ́ du ̣ 2: sử duṇ g hàm taọ có đối class Rock2 { Rock2(int i) { System.out.println( "Creating Rock number " + i); } } public class
  217. SimpleConstructor2 { public static void main(String[] args) { for(int i = 0; i < 10; i++) new Rock2(i);// goị hàm taọ có đối } }// /:~ 3. Hàm taọ măc̣ điṇ h Khi xây dưṇ g môṭ lớp mà không xây dưṇ g hàm taọ thế thì java sẽ cung cấp cho ta môṭ hàm taọ không đối măc̣ điṇ h, hàm taọ này thưc̣ chất không làm gi ̀ cả, nếu trong lớp đa ̃ có it́
  218. nhất môṭ hàm taọ thi ̀ hàm taọ măc̣ điṇ h sẽ không đươc̣ taọ ra, khi ta taọ ra môṭ đối tươṇ g thi ̀ sẽ có môṭ hàm taọ nào đó đươc̣ goị, nếu triǹ h biên dic̣ h không tim̀ thấy hàm taọ tương ứng nó sẽ thông báo lỗi, điều này thườn g xẩy ra khi chúng ta không xây dưṇ g hàm taọ không đối nhưng khi taọ dưṇ g đối tươṇ g ta laị không truyền vào tham số, như đươc̣ chi ̉ ra trong vi ́ du ̣sau: public class
  219. TestPassByValue { public TestPassByValue(String s) { System.out.println(s); } public static void main(String[] args) { TestPassByValue thu = new TestPassByValue(); // lỗi vi ̀ lớp này không có hàm taọ không đối TestPassByValue thu1 = new TestPassByValue("Hello
  220. World"); // không vấn đề gì } } 4. Goị hàm taọ từ hàm taọ Khi baṇ viết nhiều hàm taọ cho lớp, có đôi lúc baṇ muốn goị môṭ hàm taọ này từ bên trong môṭ hàm taọ khác để tránh phải viết lăp̣ mã. Để có thể goị đến hàm taọ ta sử duṇ g từ khoá this. Cú pháp this(danh sách đối số); Vi ́ du:̣
  221. public class Test { public Test () { System.out.println("hàm taọ không đối"); } public Test ( int i) { this();// goị đến hàm taọ không đối của chiń h lớp này } public static void main(String[] args) { TestPassByValue thu=new
  222. TestPassByValue(10); } } Chú ý : 1) bên trong cấu tử ta chi ̉ có thể goị đươc̣ tối đa môṭ cấu tử , điều này có nghiã là ta không thể goị đươc̣ từ 2 cấu tử trở lên bên trong môṭ cấu tử khác như đươc̣ chi ̉ ra trong vi ́ du ̣sau: public class TestPassByValue {
  223. public TestPassByVa lue() { System.out.println("Day la ham tao khong doi"); } public TestPassByVa lue(int i) { System.out.println("Day la ham tao doi so nguyen"); } public TestPassByValue(String s) { this();// không thể goị hai hàm taọ trở lên bên trong môṭ hàm taọ this(10);
  224. System.out.println("Day la ham tao doi so xau"); } public static void main(String[] args) { TestPassByValue thu = new TestPassByValue();// TestPassByValue thu1 = new TestPassByValue("Hello World");// } } 2 ) khi goị môṭ hàm taọ bên
  225. trong môṭ hàm taọ khác thì lời goị hàm taọ phải l à lêṇ h đầu tiên trong thân phương thức, nên vi ́ du ̣ sau sẽ bi ̣báo lỗi public class Test{ public Test () { System.out.println("Day la ham tao khong doi"); } public Test (String s) { System.out.println("Day la ham tao doi so xau"); this();// goị đế n cấ u tử phả i
  226. là lêṇ h đầ u tiên } public static void main(String[] args) { Test thu = new Test (“Hello World”); } } nế u cho dic̣ h vi ́ du ̣ trên triǹ h biên dic̣ h sẽ phàn nàn "Test.java": call to this must be first statement in constructor at line 7, column 9 II. Khố i khởi đầu vô danh và khố i khởi đầu tiñ h
  227. 1. Khố i vô danh Trong java ta có thể đăṭ môṭ khối lêṇ h không thuôc̣ môṭ phương thức nào, nghiã là khối này không thuôc̣ bất cứ phương thức nào kể cả hàm taọ . khi đó khối lêṇ h này đươc̣ goị là khối vô danh, khối vô danh này đươc̣ java goị thưc̣ thi khi môṭ đối tươṇ g đươc̣ taọ ra, các khối vô danh đươc̣ goị trước cả hàm taọ , thông thường ta hay sử duṇ g khối vô danh để khởi đầu các thuôc̣ tiń h của lớp hoăc̣
  228. đươc̣ sử duṇ g để khởi taọ cho các thôc̣ tiń h của môṭ lớp vô danh(vi ̀ lớp vô danh không có tên do vâỵ ta không thể viết hàm taọ cho lớp này, trong trường hơp̣ này khối vô danh là giải pháp duy nhất ) Vi ́ du:̣ ở vi ́ du ̣ này ta có 3 khối vô danh, khi chaỵ java cho thưc̣ thi các khối vô danh này theo thứ tư ̣từ trên xuống dưới public class Untitled1{
  229. // hàm taọ public Untitled1 (){ System.out.println ( "Day la ham tao" ); } // bắ t đầ u khố i vô danh { System.out.println ( "khoi khoi dau thu 3 "); }// kế t thú c khố i vô danh //bắ t đầ u khố i vô danh { System.out.println ( "khoi khoi dau thu 1 ");
  230. }//kế t thú c khố i vô danh // bắ t đầ u khố i vô danh { System.out.println ( "khoi khoi dau thu 2 "); }//kế t thú c khố i vô danh public static void main ( String[] args ) { Untitled1 dt1 = new Untitled1 (); Untitled1 dt2 = new Untitled1 (); }
  231. } khi chaỵ chương triǹ h sẽ cho kết quả sau: khoi khoi dau thu 3 khoi khoi dau thu 1 khoi khoi dau thu 2 Day la ham tao khoi khoi dau thu 3 khoi khoi dau thu 1 khoi khoi dau thu 2 Day la ham tao 2. Khố i khởi đầu tiñ h Khối khởi đầu tiñ h là môṭ khối lêṇ h bên ngoài tất cả các phương thức, kể cả hàm taọ , trước khối lêṇ h này ta đăṭ từ
  232. khoá static, từ khoá này báo cho java biết đây l à khối khởi đầu tiñ h, khối này chỉ đươc̣ goị 1 lần khi đối tươṇ g đầu tiên của lớp này đươc̣ taọ ra, khối khởi đầu tiñ h này cũng đươc̣ java goị tư ̣đôṇ g trước bất cứ hàm taọ nào, thông thường ta sử duṇ g khối khởi đầu tiñ h để khởi đầu các thuôc̣ tiń h tiñ h ( static ), sau đây là môṭ vi ́ du ̣có 1 khối khởi đầu tiñ h và môṭ khối vô danh, để baṇ thấy đươc̣ sư ̣ khác nhau giữa khối khởi đầu tiñ h và
  233. khối vô danh public class Untitled1 { public Untitled1 () { System.out.println ( "Đây là hàm taọ " ); } static {// đây là khố i khở i đầ u tĩnh System.out.println ( "Đây là khố i khở i đầ u tĩnh"); System.out.println("Khố i
  234. nà y chỉ đươc̣ goị 1 lầ n khi thể hiêṇ đầ u tiên củ a lớ p đươc̣ taọ ra"); } {//đây là khố i vô danh System.out.println ( "Đây là khố i vô danh "); } public static void main ( String[] args ) { Untitled1 dt1 = new Untitled1 ();/ / taọ ra thể hiêṇ thứ nhất của lớp
  235. Untitled1 dt2 = new Untitled1 ();/ / taọ tiếp thể hiêṇ thư 2 của lớp } } khi cho chaỵ chương triǹ h ta sẽ đươc̣ kết quả ra như sau: Đây là khối khởi đầu tiñ h Khối này chi ̉ đươc̣ goị 1 lần khi thể hiêṇ đầu tiên của lớp đươc̣ taọ ra Đây là khối vô danh Đây là hàm taọ
  236. Đây là khối vô danh Đây là hàm taọ Nhiǹ vào kết quả ra ta thấy khối khởi đầu tiñ h chi ̉ đươc̣ java goị thưc̣ hiêṇ 1 lần khi đối tươṇ g đầu tiên của lớp này đươc̣ taọ , còn khối vô danh đươc̣ goị mỗi khi môṭ đối tươṇ g mới đươc̣ taọ ra III. Doṇ dep̣ : kết thú c và thu rá c 1. Phương thứ c finalize Java không c ó phương thức hủy bỏ. Phương thức
  237. finalize tương tư ̣ như phương thức hủy bỏ của C++, tuy nhiên nó không phải là phương thức hủy bỏ. Sở di ̃ nó không phải là phương thức hủy bỏ vi ̀ khi đối tươṇ g đươc̣ hủy bỏ thi ̀ phươn g thức này chưa chắc đa ̃ đươc̣ goị đến. Phương thức này đươc̣ goị đến chi ̉ khi bô ̣thu rác của Java đươc̣ khởi đôṇ g và lúc đó đối tươṇ g không còn đươc̣ sử duṇ g nữa. D o vâỵ phương thức finalize có thể
  238. không đươc̣ goị đến. 2. Cơ chế gom rá c củ a java Người lâp̣ triǹ h C++ thường sử duṇ g toán tử new để cấp phát đôṇ g môṭ đối tươṇ g, nhưng laị thường quên goị toán tử delete để giải phóng vùng nhớ này khi không còn dùng đến nữa, điều này làm rò ri ̉ bô ̣ nhớ đôi khi dâñ đến chương triǹ h phải kết thúc môṭ cách bất thường, quả thâṭ đâu là môṭ điều tồi tê.̣ Trong java ta không cần quan tâm đến điều đó, java
  239. có môṭ cơ chế thu rác tư ̣ đôṇ g, nó đủ thông minh để biết đối tươṇ g tươṇ g nào không dùng nữa, rồi nó tư ̣đôṇ g thu hồi vùng nhớ dành cho đối tươṇ g đó. Trong ngôn ngữ C++ khi môṭ đối tươṇ g bi ̣phá huỷ, sẽ có môṭ hàm đươc̣ goị tư ̣đôṇ g, hàm này đươc̣ goị là huỷ tử hay còn goị là hàm huỷ, thông thường hàm hàm huỷ măc̣ điṇ h là đủ là đủ để doṇ dep̣ , tuy nhiên trong môṭ số trường hơp̣
  240. thi ̀ hàm huỷ măc̣ điṇ h laị không thể đáp ứng đươc̣ , do vâỵ người lâp̣ triǹ h C++, phải viết ra hàm huỷ riêng để làm viêc̣ đó, tuy nhiên java laị không có khái niêṃ hàm huỷ hay môṭ cái gi ̀ đó tương tư.̣ BÀI 3 CÁ C THÀNH PHẦ N TIÑ H I. Thuôc̣ tính tiñ h Thuôc̣ tiń h đươc̣ khai báo với từ khoá static goị là thuôc̣ tiń h tiñ h
  241. Vi ́ du:̣ class Static{ static int i = 10;// Đây là thuôc̣ tiń h tiñ h int j = 10;// Đây là thuôc̣ tiń h thường } + Các thuôc̣ tiń h tiñ h đươc̣ cấp phát môṭ vùng bô ̣ nhớ cố điṇ h, trong java bô ̣nhớ dành cho các thuôc̣ tiń h tiñ h chi ̉ đươc̣ cấp phát khi lần đầu tiên ta truy câp̣ đến nó. + Thành phần tiñ h là chung
  242. của cả lớp, nó không là của riêng môṭ đối tươṇ g nào cả. + Để truy xuấ t đế n thuôc̣ tính tiñ h ta có thể dùng môṭ trong 2 cách sau: tên_lớp.tên_thuôc̣ _tiń h_tiñ h; tên_đối_tương.tên_thuôc̣ _tiń h_ cả 2 cách truy xuất trên đều có tác duṇ g như nhau + khởi gán giá tri ̣cho thuôc̣ tiń h tiñ h thành phần tiñ h đươc̣ khởi gán bằng môṭ trong 2 cách sau: • Sử duṇ g khối khởi đầu
  243. tiñ h (xem laị bài trước ) • Sử duṇ g khởi đầu trưc̣ tiếp khi khai báo như vi ́ du ̣trên Chú ý : ta không thể sử duṇ g hà m taọ để khở i đầ u cá c thuôc̣ tí nh tĩnh, bở i vì hà m taọ không phải là phương thức tiñ h. II. Phương thứ c tiñ h Môṭ phương thức đươc̣ khai báo là static đươc̣ goị là phương thức tiñ h Vi ́ du:̣
  244. class Static{ static int i;// Đây là thuôc̣ tiń h tiñ h // phương thức tiñ h static void println (){ System.out.println ( i ); } } + Phương thức tiñ h là chung cho cả lớp, nó không lê ̣ thuôc̣ vào môṭ đối tươṇ g cu ̣ thể nào + Lời goị phương thức tiñ h xuất phát từ:
  245. t ê n của lớp: tên_lớp.tên_phương_thức_tiñ h(tham số); t ê n của đối tươṇ g: tên_đối_tương. tên_phương_thức_tiñ h(tham số); + Vi ̀ phương thức tiñ h là đôc̣ lâp̣ với đối tươṇ g do vâỵ ở bên trong phương thức tiñ h ta không thể truy câp̣ các thành viên không tiñ h của lớp đó, tức là bên trong phương thức tiñ h ta chi ̉ có thể truy câp̣ đến các
  246. thành viên tiñ h mà thôi. + Ta không thể sử duṇ g từ khoá this bên trong phương thức tiñ h BÀI 4 NAP̣ CHỒ NG PHƯƠNG THỨ C I. Khá i niêṃ về phương thứ c bôị tải Java cho phép ta xây dưṇ g nhiều phương thức trùng tên nhau, trong cùng môṭ lớp, hiêṇ tươṇ g các phương thức trong môṭ lớp có tên giống nhau đươc̣ goị là bôị
  247. tải phương thức. II. Yêu cầu củ a cá c phương thứ c bôị tải Do sử duṇ g chung môṭ cái tên cho nhiều phương thức, nên ta phải cho java biết cần phải goị phương thức nào để thưc̣ hiêṇ , java dưạ vào sư ̣ khác nhau về số lươṇ g đối cũng như kiểu dữ liêụ của các đối này để phân biêṭ các phương thức trùng tên đó. Vi ́ du:̣ public class
  248. OverloadingOrder { static void print(String s, int i) { System.out.println( "String: " + s + ", int: " + i); } static void print(int i, String s) { System.out.println( "int: " + i + ", String: " + s); } public static void main(String[] args) { print("String first", 11); print(99, "Int first");
  249. } }// /:~ Chú ý : 1) nếu nếu java không tim̀ thấy môṭ hàm bôị tải thić h hơp̣ thì nó sẽ đưa ra môṭ thông báo lỗi 2) ta không thể sử duṇ g giá tri ̣trả về của hàm để phân biêṭ sư ̣khác nhau giữa 2 phương thức bôị tải 3 ) không nên quá laṃ duṇ g các phương thức bôị tải vi ̀ triǹ h
  250. biên dic̣ h phải mất thời gian phán đoán để tim̀ ra hàm thić h hơp̣ , điều này đôi khi còn dâñ đến sai sót 4 ) khi goị các hàm nap̣ chồng ta nên có lêṇ h chuyển kiểu tường minh để triǹ h biên dic̣ h tim̀ ra hàm phù hơp̣ môṭ cách nhanh nhất 5) trong java không thể điṇ h nghiã chồng toán tử như trong ngôn ngữ C++, có thể đây là môṭ khuyết điểm,
  251. nhưng những người thiết kế java cho rằng điều này là không cần thiết, vi ̀ nó quá phức tap̣ . BÀI 5 KẾ THỪ A (INHERITANCE) I. Lớp cơ sở và lớp dâñ xuấ t - Môṭ lớp đươc̣ xây dưṇ g thông qua kế thừa từ môṭ lớp khác goị là lớp dâñ xuất (hay còn goị là lớp con, lớp hâụ duê ̣ ), lớp dùng để xây dưṇ g lớp dâñ xuất đươc̣ goị là lớp cơ sở ( hay
  252. còn goị là lớp cha, hoăc̣ lớp tổ tiên ) • Môṭ lớp dâñ xuất ngoài các thành phần của riêng nó, nó còn đươc̣ kế thừa tất cả các thành phầ n của lớp cha II. Cá ch xây dưṇ g lớp dâñ xuấ t Để nói lớp b là dâñ xuất của lớp a ta dùng từ khoá extends, cú pháp như sau: class b extends a{
  253. // phần thân của lớp b } III. Thừ a kế cá c thuôc̣ tí nh Thôc̣ tiń h của lớp cơ sở đươc̣ thừa kế trong lớp dâñ xuất, như vâỵ tâp̣ thuôc̣ tiń h của lớp dâñ xuất sẽ gồm: các thuôc̣ tiń h khai báo trong lớp dâñ xuất và các thuôc̣ tiń h của lớp cơ sở, tuy nhiên trong lớp dâñ xuất ta không thể truy câp̣ và o các thành phần private, package của lớp cơ sở
  254. IV. Thừ a kế phương thứ c Lớp dâñ xuấ t kế thừa tất cả các phương thức của lớp cơ sở trừ: • Phương thức taọ dưṇ g • Phương thức finalize V. Khở i đầ u lớ p cơ sở Lớp dâñ xuất kế thừa moị thành phần của lớp cơ, điều này dâñ ta đến môṭ hiǹ h dung, là lớp dâñ xuất có cùng giao diêṇ với lớp cơ sở và có thể có các thành phần mới bổ sung thêm. nhưng thưc̣ tế không phải vâỵ ,
  255. kế thừa không chi ̉ là sao chép giao diêṇ của lớp của lớp cơ sở. Khi ta taọ ra môṭ đối tươṇ g của lớp suy dâñ , thi ̀ nó chứa bên trong nó môṭ sư ̣vâṭ con của lớp cơ sở, sư ̣ vâṭ con này như thể ta đa ̃ taọ ra môṭ sư ̣ vâṭ tường minh của lớp cơ sở, thế thi ̀ lớp cơ sở phải đươc̣ bảo đảm khởi đầ u đú ng, để thưc̣ hiêṇ điề u đó troṇ g java ta làm như sau: Thưc̣ hiêṇ khở i đầ u cho lớ p
  256. cơ sở bằ ng cá ch goị cấ u tử củ a lớ p cơ sở bên trong cấ u tử củ a lớ p dẫ n xuấ t, nế u baṇ không là m điề u nà y thì java sẽ là m giú p ban, nghĩa là java luôn tư ̣ đôṇ g thêm lờ i goị cấ u tử củ a lớ p cơ sở và o cấ u tử củ a lớ p dẫ n xuấ t nế u như ta quên là m điề u đó , để có thể goị cấ u tử củ a lớ p cơ sở ta sử duṇ g từ khoá super V i ́ du ̣ 1: vi ́ du ̣ này không goị cấu tử của lớp cơ sở môṭ cách tường minh class B
  257. { public B () { System.out.println ( "Ham tao của lop co so" ); } } public class A extends B { public A () {// không goị hàm taọ của
  258. lớp cơ sở tường minh System.out.println ( "Ham tao của lop dan xuat" ); } public static void main ( String arg[] ) { A thu = new A (); } } Kết quả chaỵ chương triǹ h như sau: Ham tao của lop co so Ham tao của lop dan xuat
  259. Vi ́ du ̣2: vi ́ du ̣này sử duṇ g từ khoá super để goị cấu tử của lớp cơ sở môṭ cách tường minh class B { public B () { System.out.println ( "Ham tao của lop co so" ); } } public class A
  260. extends B { public A () { super();// goị taọ của lớp cơ sở môṭ cách tường minh System.out.println ( "Ham tao của lop dan xuat" ); } public static void main ( String arg[] ) { A thu = new A (); }
  261. } khi chaỵ chưng triǹ h ta thấy kết quả giống hêṭ như vi ́ du ̣trên Chú ý 1: nếu goị tường minh cấu tử của lớp cơ sở, thi ̀ lời goị này phải là lêṇ h đầu tiên, nếu ví du ̣trên đổi thành class B { public B () { System.out.println ( "Ham tao của lop co so" ); }
  262. } public class A extends B { public A () { // Lời goị cấu tử của lớp cơ sở không phải là lêṇ h đầu tiên System.out.pr in t ln ("Ham t a o của lop dan xuat"); super (); } public static void main ( String arg[] )
  263. { A thu = new A (); } } nế u biên dic̣ h đoaṇ mã này ta sẽ nhân đươc̣ môṭ thông b á o lỗi như sau: "A.java": call to super must be first statement in constructor at line 15, column 15 Chú ý 2: ta chỉ có thể goị đến môṭ hàm taọ của lớp cơ sở bên trong hàm taọ của lớp dâñ xuất, vi ́ du ̣ chi ̉ ra sau đã bi ̣báo
  264. lỗi class B { public B () { System.out.println ( "Ham tao của lop co so" ); } public B ( int i ) { System.out.println ( "Ham tao của lop co so" ); }
  265. } public class A extends B { public A () { super (); super ( 10 );/ / không thể goị nhiều hơn 1 hàm taọ của lớp cơ sở System.out.println ( "Ham tao của lop dan xuat" ); } public static void main (
  266. String arg[] ) { A thu = new A (); } } 1. Trâṭ tư ̣khở i đầ u Trâṭ tư ̣ khởi đầu trong java đươc̣ thưc̣ hiêṇ theo nguyên tắc sau: java sẽ goị cấu tử của lớp cơ sở trước sau đó mới đến cấu tử của lớp suy dâñ , điều này có nghiã là trong cây phả hê ̣ thì các cấu tử sẽ đươc̣ goị theo trâṭ tư ̣từ gốc xuống dần đến lá
  267. 2. Trâṭ tư ̣doṇ dep̣ Măc̣ dù java không có khái niêṃ huỷ tử như của C++, tuy nhiên bô ̣ thu rác của java vâñ hoaṭ đôṇ g theo nguyên tắc làm viêc̣ của cấu tử C++, tức là trâṭ tư ̣thu rác thi ̀ ngươc̣ laị so với trâṭ tư ̣khởi đầu. VI. Ghi đè phương thứ c ( Override ) Hiêṇ tươṇ g trong lớp cơ sở và lớp dâñ xuất có hai phương
  268. thức giống hêṭ nhau ( cả tên lẫn bô ̣ tham số) goị là ghi đè phương thức ( Override ) , c h ú ý Override khác Overload. Goị phương thứ c bi ̣ghi đè củ a lớ p cơ sở Bên trong lớp dâñ xuất, nếu có hiêṇ tươṇ g ghi đè thi ̀ phương thức bi g̣ hi đè của lớp cơ sở sẽ bi ̣ẩn đi, để có thể goị phương thức bi ̣ghi đè của lớp cơ sở ta dùng từ khoá super để truy câp̣ đến
  269. lớp cha, cú pháp sau: super.overriddenMethodName Chú ý : Nếu môṭ phương thức của lớp cơ sở bi ̣bôị tải ( Overload ), thi ̀ nó không thể bi ̣ ghi đè ( Override ) ở lớp dâñ xuất. VI. Thà nh phầ n protected Trong môṭ vài bài trước ta đa ̃ làm quen với các thành phần private, public, sau khi đã hoc̣ về kế thừa thi ̀ từ khoá protected cuối cùng đa ̃ có ý nghiã . Từ khoá protected báo cho
  270. java biết đây là thành phần riêng tư đối với bên ngoài nhưng laị săñ sàng với các con cháu VII. Từ khoá final Từ khoá final trong java có nhiều nghiã khác nhau, nghiã của nó tuỳ thuôc̣ vào ngữ cảnh cu ̣ thể , nhưng nói chung nó muốn nó i “cái nà y không thể thay đổi đươc̣ ”. 1. Thuôc̣ tí nh final
  271. Trong java cách duy nhấ t để taọ ra môṭ hằng là khai báo thuôc̣ tiń h là final Vi ́ du:̣ public class A { // điṇ h nghiã hằng tên MAX_VALUE giá tri 1̣ 00 static final int MAX_VALUE = 100; public static void main ( String arg[] ) {
  272. } } Chú ý : A thu = new A (); System.out.println("MAX_VALU " +thu.MAX_VALUE); 1 ) khi đa ̃ khai báo môṭ thuôc̣ tiń h là final thi ̀ thuôc̣ tiń h này la hăng, do vâỵ ta không thể thay đổi giá tri c̣ ủa nó 2) khi khai báo môṭ thuôc̣ tiń h là final thi ̀ ta phải cung cấp giá tri ḅ an đầu cho nó 3 ) nếu môṭ thuôc̣ tiń h vừa là
  273. final vừa là static thi ̀ nó chi ̉ có môṭ vùng nhớ chung duy nhất cho cả lớp 2. Đố i số final Java cho phép ta taọ ra các đối final bằng viêc̣ khai báo chúng như vâỵ bên trong danh sách đối, nghiã là bên trong thân của phương pháp này, bất cứ cố gắng nào để thay đổi giá tri ̣ của đối đều gây ra lỗi lúc dic̣ h Vi ́ du ̣ sau bi ̣báo lỗi lúc dic̣ h vi ̀ nó cố gắng thay đổi giá tri ̣
  274. của đối final public class A { static public void thu ( final int i ) { i=i+1;//không cho phép thay đổi giá tri c̣ ủa tham số final System.out.println ( i );; } public static void main ( String arg[] ) { int i = 100;
  275. thu ( i ); } } chương triǹ h này sẽ bi ̣ báo lỗi: "A.java": variable i might already have been assigned to at line 5, column 9 3. Phương thứ c final Môṭ phương thức biǹ h thường có thể bi ̣ ghi đè ở lớp dâñ xuất, đôi khi ta không muốn phương thức của ta bi ̣ghi đè ở lớp dâñ xuất vi ̀ lý do gi ̀ đó,
  276. muc̣ đić h chủ yếu của các phương thức final là tránh ghi đè, tuy nhiên ta thấy rằn g các phương thức private sẽ tư ̣ đôṇ g là final vi ̀ chúng không thể thấy đươc̣ trong lớp dâñ xuất lên chúng không thể bi ̣ghi đè, nên cho dù baṇ có cho môṭ phương thức private là final thi ̀ baṇ cũng chả thấy môṭ hiêụ ứng nào 4. Lớ p final Nếu baṇ không muốn người khác kế thừa từ lớp của baṇ , thì baṇ hãy dùng
  277. từ khoá final để ngăn cản bất cứ ai muốn kế thừa từ lớp này. Chú ý : do môṭ lớ p là final (tứ c không thể kế thừ a )do vâỵ ta không thể nà o ghi đè các phương thức của lớp này, do vâỵ đừng cố gắng cho môṭ phương thức của lớp final là final BÀI 6 LỚ P CƠ SỞ TRỪ U TƯƠṆ G Môṭ lớp cơ sở trừu tươṇ g là
  278. môṭ lớp chi ̉ đươc̣ dùng làm cơ sở cho các lớp khác, ta không thể taọ ra thể hiêṇ của lớp này, bởi vi ̀ nó đươc̣ dùng để điṇ h nghiã môṭ giao diêṇ chung cho các lớp khác. Phương thứ c trừu tươṇ g Môṭ lớp trừu tươṇ g có thể chứa môṭ vài phương thức trừu tươṇ g, d o lớ p trừu tươṇ g chi ̉ làm lớp cơ sở cho các lớp khác, do vâỵ các phương thức trừu tươṇ g cũng không đươc̣ cài đăṭ cu ̣ thể,
  279. chúng chi ̉ gồm có khai báo, viêc̣ cài đăṭ cu ̣ thể sẽ dành cho lớp con 1. Chú ý: 1 ) nếu trong lớp có phương thức trừu tươṇ g thi ̀ lớp đó phải đươc̣ khai báo là trừu tươṇ g 2) nếu môṭ lớp kế thừa từ lớp trừu tươṇ g thi:̀ hoăc̣ chúng phải ghi đè tất cả các phương thức ảo của lớp cha, hoăc̣ lớp đó phải là lớp trừu tươṇ g 3) không thể taọ ra đối
  280. tươṇ g của lớp trừu tươṇ g BÀ I 7 ĐA HÌNH THÁ I Đa hiǹ h thái trong lâp̣ triǹ h hướng đối tươṇ g đề câp̣ đến khả năng quyế t điṇ h trong lúc thi hành (runtime) ma ̃ nào sẽ đươc̣ chaỵ , khi có nhiều phương thức trùng tên nhau nhưng ở các lớp có cấp bâc̣ khác nhau. Chú ý : khả năng đa hì nh thá i trong lâp̣ trì nh hướ ng đố i tươṇ g cò n đươc̣ goị vớ i
  281. nhiều cái tên khác nhau như: tương ứng bôị, kết ghép đôṇ g, Đa hiǹ h thái cho phép các vấn đề khác nhau, các đối tươṇ g khác nhau, các phương thức khác nhau, các cách giải quyết khác nhau theo cùng môṭ lươc̣ đồ chung. C á c bước để taọ đa hiǹ h thái: 1 . Xây dưṇ g lớp cơ sở ( thường là lớp cơ sở trừu tươṇ g, hoăc̣ là môṭ giao diêṇ ), lớp này sẽ đươc̣ các
  282. lớp con mở rôṇ g( đối với lớp thường, hoăc̣ lớp trừu tươṇ g), hoăc̣ triển khai chi tiết ( đối với giao diêṇ ). 2. 2. Xây dưṇ g các lớp dâñ xuất từ lớp cơ sở vừa taọ . trong lớp dâñ xuất này ta sẽ ghi đè các phương thức của lớp cơ sở( đối với lớp cơ sở thường), hoăc̣ triển khai chi tiết nó ( đối với lớp cơ sở trừu tươṇ g hoăc̣ giao diêṇ ). 3. Thưc̣ hiêṇ viêc̣ taọ khuôn xuống, thông qua lớp cơ sở,
  283. để thưc̣ hiêṇ hành vi đa hiǹ h thái Khái niêṃ về taọ khuôn lên, taọ khuôn xuống • Hiêṇ tươṇ g môṭ đối tươṇ g của lớp cha tham trỏ đến môṭ đối tươṇ g của lớp con thi ̀ đươc̣ goị là taọ khuôn xuống, viêc̣ taọ khuôn xuống luôn đươc̣ java chấp thuâṇ , do vâỵ khi taọ khuôn xuống ta không cần phải ép kiểu tường minh. • Hiêṇ tươṇ g môṭ đối
  284. tươṇ g của lớp con tham trỏ tới môṭ đối tươṇ g của lớp cha thi ̀ đươc̣ goị là taọ khuôn lên, viêc̣ taọ khuôn lên là an toàn, vì môṭ đối tươṇ g của lớp con cũng có đầ y đủ các thành phần của lớp cha, tuy nhiên viêc̣ taọ khuôn lên sẽ bi ḅ áo lỗi nếu như ta không ép kiể u môṭ cách tường minh. BÀ I 8 GIAO DIÊṆ , LỚ P TRONG, GÓ I Giao diêṇ là môṭ khái niêṃ