lp trình hướng đi tượng lthđt
LẬP TRÌNH HƯỚNG ĐỐI
NG
ÔN TẬP CUỐI KỲ
BIÊN SO N:
ThS.TRANMINHNHAT
UML
Use case
Biểu đồ ạt đồ ho ng ( ACTIVE DIAGRAM)
COLLECTION
1. ARRAYLIST
a. Add và In ra các thông tin trong arraylist
b. i 1 thông tin trong arraylist ( vd v trí s 2: (SET) Thay đổ
cam )
c. (Remove) xóa 1 thông tin khi bi t v trí ế
d. Xóa khi không bi t v trí ế
e. Kim tra xem có thông tin này ko ( cà chua )
Nếu có tr v true , ko có tr v false
Bài t p m u
Ví d 1: Viết chương trình quản lý sinh viên dưới dng console, yêu c u s d ng ArrayList
hoc LinkedList Vector hoc và th c hi n các ch ức năng sau (thông tin sinh viên bao gồm: mã
s sinh viên, h tên, năm sinh, địa ch, lp h :c)
a) Cho phép thêm, s a, xóa danh sách sinh viên
b) Xu t ra s lượng sinh viên
c) Xu t ra danh sách các sinh viên thu c m t l p h c b t k p vào t bàn phím nh
Câu a . Cho phép thêm, s a, xóa danh sách
sinh viên
// Class Sinhvien
package chap2.quanlysinhvien;
import java.util.Date;
public class Sinhvien {
private String Masv;
private String Tensv;
private Date Namsinh;
private String Diachi;
private String Lop;
public String getMasv() {
return Masv;
}
public void setMasv(String masv) {
Masv = masv;
}
public String getTensv() {
return Tensv;
}
public void setTensv(String tensv) {
Tensv = tensv;
}
public Date getNamsinh() {
return Namsinh;
}
public void setNamsinh(Date namsinh) {
Namsinh = namsinh;
}
public String getDiachi() {
return Diachi;
}
public void setDiachi(String diachi) {
Diachi = diachi;
}
public String getLop() {
return Lop;
}
public void setLop(String lop) {
Lop = lop;
}
public String toString() {
return "Sinhvien [Masv=" + Masv + ",
Tensv=" + Tensv + ", Namsinh="
+ Namsinh + ", Diachi=" + Diachi + ",
Lop=" + Lop + "]";
}
}
//Class DanhSachSinhvien
package chap2.quanlysinhvien;
import java.util.ArrayList;
public class DanhSachSinhvien {
private ArrayList<Sinhvien> dsSv = new
ArrayList<Sinhvien>();
public boolean ktTrungma(String masv) {
for (Sinhvien sv : dsSv) {
if
(sv.getMasv().equalsIgnoreCase(masv))
return true;
}
return false;
}
public boolean addSinhvien(Sinhvien sv) {
(ktTrungma(sv.getMasv())) if
return false;
return dsSv.add(sv);
}
public Sinhvien findSinhvien1(String masv) {
for (Sinhvien sv : dsSv) {
if
(sv.getMasv().equalsIgnoreCase(masv))
return sv;
}
return null;
}
public int findSinhvien2(String masv) {
for (int i = 0; i < dsSv.size(); i++) {
if
(dsSv.get(i).getMasv().equalsIgnoreCase(masv
))
return i;
}
return - 1;
}
public Sinhvien updateSinhvien(int index,
Sinhvien sv) {
return dsSv.set(index, sv);
}
public void removeSinhvien(String masv) {
Sinhvien sv = findSinhvien1(masv);
dsSv.remove(sv);
}
public String toString() {
return dsSv.toString();
}
}
//Class TestSinhvien
package chap2.quanlysinhvien;
public class TestSinhvien {
public static void main(String[] args) {
DanhSachSinhvien qlsv = new
DanhSachSinhvien();
Sinhvien teo = new Sinhvien();
teo.setMasv("113");
teo.setTensv("Nguy ễn Văn Tèo");
qlsv.addSinhvien(teo);
Sinhvien ty = new Sinhvien();
ty.setMasv("114");
ty.setTensv("Nguy n Th tý");
qlsv.addSinhvien(ty);
System.out.println(qlsv);
}
}
Câu b: Xuất ra số ợng sinh viên
// Class DanhSachSinhvien
package chap2.quanlysinhvien;
import java.util.ArrayList;
public class DanhSachSinhvien {
private ArrayList<Sinhvien> dsSv = new
ArrayList<Sinhvien>();
// Các phương thức khác đã được định
nghĩa ở câu a
public int countSinhvien() {
return dsSv.size();
}
// Phương thức main để kim tra
public static void main(String[] args) {
DanhSachSinhvien qlsv = new
DanhSachSinhvien();
Sinhvien teo = new Sinhvien();
teo.setMasv("113");
teo.setTensv("Nguy ễn Văn Tèo");
qlsv.addSinhvien(teo);
Sinhvien ty = new Sinhvien();
ty.setMasv("114" );
ty.setTensv("Nguy n Th Tý");
qlsv.addSinhvien(ty);
System.out.println("S ng sinh viên: " + lượ
qlsv.countSinhvien());
}
}
Câu c: Xuất ra danh sách các sinh viên thuộc
một lớp học bất kỳ ập vào từ bàn phímnh
// Class DanhSachSinhvien
package chap2.quanlysinhvien;
import java.util.ArrayList;
import java.util.Scanner;
public class DanhSachSinhvien {
private ArrayList<Sinhvien> dsSv = new
ArrayList<Sinhvien>();
// Các phương thức khác đã được định nghĩa
câu a
public void printSinhvienByClass(String lop) {
System.out.println("Danh sách sinh viên
trong l p " + lop + ":");
for (Sinhvien sv : dsSv) {
if (sv.getLop().equalsIgnoreCase(lop)) {
System.out.println(sv);
}
}
}
// Phương thức main để kim tra
public static void main(String[] args) {
DanhSachSinhvien qlsv = new
DanhSachSinhvien();
Sinhvien teo = new Sinhvien();
teo.setMasv("113");
teo.setTensv("Nguyễn Văn Tèo");
teo.setLop("A1");
qlsv.addSinhvien(teo);
Sinhvien ty = new Sinhvien();
ty.setMasv("114");
ty.setTensv("Nguy n Th Tý");
ty.setLop("A2");
qlsv.addSinhvien(ty);
Scanner scanner = new
Scanner(System.in);
System.out.print("Nh p l p h c c n tìm: ");
String lop = scanner.nextLine();
qlsv.printSinhvienByClass(lop);
}
}
CLASS DIAGRAM ( bi l p )ểu đồ
//Inheritance: k a ( developer và designer person) ế th
//association: liên k t ko rõ ( vd ko bi t designer liên k t ntn v i project có th ) ế ế ế dùng
// aggregation (hình thoi tr ng): developer works on project
// n ếu developer ngh vic thì project vn còn ko ảnh hưởng
//hình thoi đen: kitchen và restroom phụ ếu cty cháy 2 cái đấy cũng mấ thuc vào company ( n t
)
// s 1..* : 1 cty có th có 1 restroom ho c nhi u phòng t m
// 2..10: 1 cty ch có th có t n 10 kitchen 2 đế
UML ng tác trình t Sequence diagram Biểu đ tươ
(SD)
Alt: dùng để if else
Lý thuy t ế
1. K a ế th
Kế thừa trong Java là gì?
Kế thừa (inheritance) trong Java một tính năng của lập trình hướng đối ợng, cho phép một lớp
(class) mới tiếp nhận các thuộc tính và phương thức của một lớp khác. Lớp mới được gọi là lớp con
(subclass), và lớp mà nó kế thừa được gọi là lớp cha (superclass). Kế thừa giúp tái sử dụng mã nguồn,
giảm độ lặp lại và tăng tính mô đun của chương trình.-
Các thuật ngữ quan trọng trong kế thừa Java:
Lớp cha (Superclass): Lớp các thuộc tính phương thức được kế thừa bởi lớp
con.
Lớp con (Subclass): Lớp kế thừa các thuộc tính và phương thức từ lớp cha.
extends: Từ khóa dùng để chỉ rõ lớp con kế thừa từ lớp cha.
super: Từ khóa dùng để truy cập các thuộc tính và phương thức của lớp cha từ lớp con.
2. Đa hình
Tính đa hình (polymorphism) trong Java là gì?
Trong Java, tính đa hình được thể hiện qua việc cho phép một biến tham chiếu có thể trỏ
đến các đối tượng thuộc các lớp khác nhau, miễn chúng kế thừa từ một lớp chung. Điều này giúp
chúng ta thể xây dựng các hệ thống phần mềm linh hoạt và dễ mở rộng hơn. Biến tham chiếu ở đây
được sử dụng để lưu trữ địa chỉ bộ nhớ của đối tượng đó (tương tnhư số nhà của bạn vậy) và mỗi
biến tham chiếu sẽ tương ứng cho mỗi đối tượng
Giả sử chúng ta có lớp NhanVien kế thừa từ lớp ConNguoi. Một biến tham chiếu có thể trỏ
đến đối tượng thuộc lớp ConNguoi hoặc đối tượng thuộc lớp NhanVien, biến tham chiếu nv1, nv2,nv3,…
Trong ngữ cảnh này, chúng ta có thể gọi phương thức thongTin của lớp ConNguoi hoặc lớp NhanVien
thông qua biến tham chiếu đó
.
Overriding (Ghi đè)
Overriding kỹ thuật cho phép lớp con định nghĩa lại phương thức của lớp cha với cùng tên, cùng
tham số và cùng kiểu trả về. Khi gọi phương thức thông qua đối tượng của lớp con, phương thức của
lớp con sẽ được thực thi thay vì phương thức của lớp cha.
Nó giống như việc bạn được chỉ định để thực hiện nhiệm vụ đó bởi một người quản lý. Bạn nhận thấy
một cách để thực hiện công việc tốt hơn so với cách ban đầu. Bạn quyết định áp dụng ch của
mình và thông báo cho người quản lý.
Ví dụ:
class ConNguoi {
void hienThi() {
System.out.println(“Tôi là con người.”);
}
}
class NhanVien extends ConNguoi {
void hienThi() {
System.out.println(“Tôi là nhân viên.”);
}
}
public class Main {
public static void main(String[] args) {
ConNguoi conNguoi = new NhanVien();
conNguoi.hienThi(); // In ra: “Tôi là nhân viên.”
}
}
Overloading (Ghi chồng)
Overloading là kỹ thuật tạo ra nhiều phương thức cùng tên nhưng khác nhau về số lượng hoặc kiểu
dữ liệu của tham số. Các phương thức được gọi tương ứng vi c tham số truyền vào. Môt ví dụ thực
tế để bạn dễ hiểu hơn máy giặt nhiều chế độ giặt khác nhau. Máy giặt sử dụng kỹ thuật nạp chồng
(overloading) để cung cấp cho bạn nhiều tùy chọn khác nhau như giặt nhanh, giặt êm, giặt bằng nước
nóng để giặt các loại quần áo khác nhau.
Ví dụ:
class HinhChuNhat {
double tinhDienTich(double chieuDai, double chieuRong) {
return chieuDai * chieuRong;
}
double tinhDienTich(double canh) {
return canh * canh;
}
}
Tại sao sử dụng tính đa hình trong Java?
Đa hình (Polymorphism) trong Java cho phép viết một phương thức có thể xử lý chính xác nhiều loại
chức năng khác nhau có cùng tên. Chúng ta cũng có thể đạt được tính nhất quán trong mã của mình
bằng cách sử dụng đa hình.
Ưu điểm của đa hình trong Java
Nó cung cấp khả năng tái sử dụng cho mã.Chúng ta có thể tận dụng các lớp và phương
thức đã được định nghĩa trước để triển khai các chức năng mới không cần viết lại
nguồn từ đầu. Ngoài ra, người lập trình có thể thay đổi mã mà không ảnh hưởng đến
mã gốc.
Cho phép tạo ra các lớp con có tính chất riêng của chúng sử dụng chúng trong một
cấu trúc kế thừa phức tạp hơn.
Với ít dòng mã hơn, người lập trình dễ dàng hơn trong việc sửa lỗi mã.
Nhược điểm của tính đa hình trong Java
Tính đa hình có thể làm tăng độ phức tạp của mã nguồn và khó hiểu hơn, đặc biệt là khi
sử dụng nhiều lớp con kế thừa từ cùng một lớp cha.
Tính đa hình có thể làm giảm hiệu suất của chương trình trong một số trường hợp. Khi
chúng ta sử dụng đa hình, Java phải tìm kiếm phương thức thích hợp để thực thi, điều
này có thể làm giảm hiệu suất.
Tuy nhiên chúng ta vẫn cải thiện nhược điểm của tính đa hình trong Java bằng việc sdụng các
các thiết kế mẫu (design patterns), áp dụng các kỹ thuật và các công cụ hỗ trợ khác như Kotlin, Scala
hoặc IDE như Eclipse,…
So sánh Linkedlist và Arraylist ( collections )
Giống: cả 2 đều dùng để lưu trữ danh sách.
ArrayList dùng một mảng động (như mảng thường nhưng thể thay đổi kích
thước và các phương thức thêm) để lưu trữ phần tử.
LinkedList sử dụng danh sách liên kết để lưu trữ phần tử. Mỗi phần thử có thể được
gọi là 1 node trong danh sách.
khác:
1. Cách lưu trữ phần tử: Định nghĩa đã nêu rõ rồi đúng không nào
2. ArrayList thêm xóa phần tử chậm hơn LinkedList: Điều này khá dễ hiểu
LinkedList chỉ cần thay đổi luồng trỏ của các node trong danh sách nên độ phức tạp
là O(1) còn ArrayList phải tăng/lùi tất cả những vị trí sau vị trí muốn thêm/xóa nên
độ phức tạp là O(n).
3. ArrayList truy xuất phần tử nhanh hơn LinkedList: ArrayList muốn truy xuất đến phân
tử thứ mấy trong danh sách thì chỉ cần gọi vị trí đó ra là được nên mất O(1) phức
tạp, còn LinkedList thì phải duyệt qua các phần tử trước đó thì mới truy xuất được
đến phần tử cần lấy nên độ phức tạp là O(n)
4. ArrayList chỉ thể hoạt động như 1 list thông thường, còn LinkedList thhoạt
động như ArrayList, stack, queue. (stack và queue mình sẽ nói đến bài blog khác
nhé)
5. ArrayList yêu cầu ít bộ nhớ hơn LinkedList: Vì ngoài lưu trữ giá trị thì các node trong
LinkedList còn phải chứa các tham chiếu đến phần tử trước, sau của nó nữa.
Như vậy mọi người có lẽ đã hiểu rõ về 2 loại danh sách thường sử dụng này.
So sánh HashSet, LinkedHashSet và TreeSet
Giống:
C ba không cho phép các ph n t trùng l p.
C ba không được đồng b (non-synchronized).
C ba đều cài đặt interface Cloneable Serializable.
C u là fail-fast. B n s ba đề nhận được ConcurrentModificationException nếu chúng đượ ửa đổc s i
sau khi tạo đối tượng Iterator.
Khác

Preview text:

lập trình hướng đối tượng lthđt
LẬP TRÌNH HƯỚNG ĐỐI TƯỢNG ÔN TẬP CUỐI KỲ BIÊN SON: ThS.TRANMINHNHAT UML Use case
Biểu đồ h
o t đồng ( ACTIVE DIAGRAM) COLLECTION 1. ARRAYLIST
a. Add và In ra các thông tin trong arraylist
b. (SET) Thay đổi 1 thông tin trong arraylist ( vd v trí s 2: cam )
c. (Remove) xóa 1 thông tin khi biết v trí
d. Xóa khi không biết v trí
e. Kim tra xem có thông tin này ko ( cà chua )
Nếu có tr v true , ko có tr v false
Bài tp mu
Ví d 1: Viết chương trình quản lý sinh viên dưới dạng console, yêu cầu sử dụng ArrayList
hoặc LinkedList hoặc Vector và thực hiện các chức năng sau (thông tin sinh viên bao gồm: mã
số sinh viên, họ tên, năm sinh, địa chỉ, lớp học):
a) Cho phép thêm, sửa, xóa danh sách sinh viên
b) Xuất ra số lượng sinh viên
c) Xuất ra danh sách các sinh viên thuộc một lớp học bất kỳ nhập vào từ bàn phím
Câu a . Cho phép thêm, sa, xóa danh sách public String getMasv() { sinh viên return Masv; // Class Sinhvien } package chap2.quanlysinhvien;
public void setMasv(String masv) { import java.util.Date; Masv = masv; } public class Sinhvien { private String Masv; public String getTensv() { private String Tensv; return Tensv; private Date Namsinh; } private String Diachi; private String Lop;
public void setTensv(String tensv) { Tensv = tensv; } } } public Date getNamsinh() { return Namsinh; } //Class DanhSachSinhvien package chap2.quanlysinhvien;
public void setNamsinh(Date namsinh) { Namsinh = namsinh; import java.util.ArrayList; }
public class DanhSachSinhvien { public String getDiachi() { private ArrayList dsSv = new ArrayList(); return Diachi; }
public boolean ktTrungma(String masv) { for (Sinhvien sv : dsSv) {
public void setDiachi(String diachi) { if Diachi = diachi;
(sv.getMasv().equalsIgnoreCase(masv)) } return true; } public String getLop() { return false; return Lop; } }
public boolean addSinhvien(Sinhvien sv) {
public void setLop(String lop) { if (ktTrungma(sv.getMasv())) Lop = lop; return false; } return dsSv.add(sv); } public String toString() {
return "Sinhvien [Masv=" + Masv + ",
public Sinhvien findSinhvien1(String masv) {
Tensv=" + Tensv + ", Namsinh=" for (Sinhvien sv : dsSv) {
+ Namsinh + ", Diachi=" + Diachi + ", Lop=" + Lop + "]"; if
(sv.getMasv().equalsIgnoreCase(masv)) //Class TestSinhvien return sv; package chap2.quanlysinhvien; } return null; public class TestSinhvien { }
public static void main(String[] args) { DanhSachSinhvien qlsv = new
public int findSinhvien2(String masv) { DanhSachSinhvien();
for (int i = 0; i < dsSv.size(); i++) {
Sinhvien teo = new Sinhvien(); if teo.setMasv("113");
(dsSv.get(i).getMasv().equalsIgnoreCase(masv ))
teo.setTensv("Nguyễn Văn Tèo"); qlsv.addSinhvien(teo); return i;
Sinhvien ty = new Sinhvien(); } ty.setMasv("114"); return -1; }
ty.setTensv("Nguyễn Thị tý"); qlsv.addSinhvien(ty); System.out.println(qlsv);
public Sinhvien updateSinhvien(int index, Sinhvien sv) { } return dsSv.set(index, sv); } }
public void removeSinhvien(String masv) {
Sinhvien sv = findSinhvien1(masv); dsSv.remove(sv); } public String toString() { return dsSv.toString();
Câu b: Xuất ra số l ợng sinh viên ư } // Class DanhSachSinhvien } package chap2.quanlysinhvien; import java.util.ArrayList;
public class DanhSachSinhvien { // Class DanhSachSinhvien private ArrayList dsSv = new package chap2.quanlysinhvien; ArrayList(); import java.util.ArrayList; import java.util.Scanner;
// Các phương thức khác đã được định nghĩa ở câu a
public class DanhSachSinhvien { public int countSinhvien() { private ArrayList dsSv = new ArrayList(); return dsSv.size(); }
// Các phương thức khác đã được định nghĩa ở câu a
// Phương thức main để kim tra
public static void main(String[] args) {
public void printSinhvienByClass(String lop) { DanhSachSinhvien qlsv = new
System.out.println("Danh sách sinh viên DanhSachSinhvien(); trong lớp " + lop + ":");
Sinhvien teo = new Sinhvien(); for (Sinhvien sv : dsSv) { teo.setMasv("113");
if (sv.getLop().equalsIgnoreCase(lop)) {
teo.setTensv("Nguyễn Văn Tèo"); System.out.println(sv); qlsv.addSinhvien(teo); }
Sinhvien ty = new Sinhvien(); } ty.setMasv("114") ; }
ty.setTensv("Nguyễn Thị Tý"); qlsv.addSinhvien(ty);
// Phương thức main để kim tra
public static void main(String[] args) {
System.out.println("Số lượng sinh viên: " + DanhSachSinhvien qlsv = new qlsv.countSinhvien()); DanhSachSinhvien(); }
Sinhvien teo = new Sinhvien(); } teo.setMasv("113");
teo.setTensv("Nguyễn Văn Tèo"); teo.setLop("A1");
Câu c: Xuất ra danh sách các sinh viên thuộc qlsv.addSinhvien(teo);
một lớp học bất kỳ nhập vào từ bàn phím
Sinhvien ty = new Sinhvien(); ty.setMasv("114");
ty.setTensv("Nguyễn Thị Tý"); ty.setLop("A2"); qlsv.addSinhvien(ty); Scanner scanner = new Scanner(System.in);
System.out.print("Nhập lớp học cần tìm: ");
String lop = scanner.nextLine();
qlsv.printSinhvienByClass(lop); } }
CLASS DIAGRAM ( biểu đồ lp )
//Inheritance: kế tha ( developer và designer person)
//association: liên kết ko rõ ( vd ko biết designer liên kết ntn vi project có th dùng )
// aggregation (hình thoi trng): developer works on project
// nếu developer ngh vic thì project vn còn ko ảnh hưởn g
//hình thoi đen: kitchen và restroom phụ thuc vào company ( nếu cty cháy 2 cái đấy cũng mất )
// s 1..* : 1 cty có th có 1 restroom hoc nhiu phòng tm
// 2..10: 1 cty ch có th có t n 10 kitchen 2 đế
UML Biểu đồ tương tác trình t Sequence diagram (SD)
Alt: dùng để if else Lý thuyết 1. Kế tha
Kế thừa trong Java là gì?
Kế thừa (inheritance) trong Java là một tính năng của lập trình hướng đối tượng, cho phép một lớp
(class) mới tiếp nhận các thuộc tính và phương thức của một lớp khác. Lớp mới được gọi là lớp con
(subclass), và lớp mà nó kế thừa được gọi là lớp cha (superclass). Kế thừa giúp tái sử dụng mã nguồn,
giảm độ lặp lại và tăng tính mô-đun của chương trình.
Các thuật ngữ quan trọng trong kế thừa Java: 
Lớp cha (Superclass): Lớp mà các thuộc tính và phương thức được kế thừa bởi lớp con. 
Lớp con (Subclass): Lớp kế thừa các thuộc tính và phương thức từ lớp cha. 
extends: Từ khóa dùng để chỉ rõ lớp
con kế thừa từ lớp cha. 
super: Từ khóa dùng để truy cập các thuộc tính và phương thức của lớp cha từ lớp con. 2. Đa hình
Tính đa hình (polymorphism) trong Java là gì?
Trong Java, tính đa hình được thể hiện qua việc cho phép một biến tham chiếu có thể trỏ
đến các đối tượng thuộc các lớp khác nhau, miễn là chúng kế thừa từ một lớp chung. Điều này giúp
chúng ta có thể xây dựng các hệ thống phần mềm linh hoạt và dễ mở rộng hơn. Biến tham chiếu ở đây
được sử dụng để lưu trữ địa chỉ bộ nhớ của đối tượng đó (tương tự như số nhà của bạn vậy) và mỗi
biến tham chiếu sẽ tương ứng cho mỗi đối tượng
Giả sử chúng ta có lớp NhanVien kế thừa từ lớp ConNguoi. Một biến tham chiếu có thể trỏ
đến đối tượng thuộc lớp ConNguoi hoặc đối tượng thuộc lớp NhanVien, biến tham chiếu nv1, nv2,nv3,…
Trong ngữ cảnh này, chúng ta có thể gọi phương thức thongTin của lớp ConNguoi hoặc lớp NhanVien
thông qua biến tham chiếu đó . Overriding (Ghi đè)
Overriding là kỹ thuật cho phép lớp con định nghĩa lại phương thức của lớp cha với cùng tên, cùng
tham số và cùng kiểu trả về. Khi gọi phương thức thông qua đối tượng của lớp con, phương thức của
lớp con sẽ được thực thi thay vì phương thức của lớp cha.
Nó giống như việc bạn được chỉ định để thực hiện nhiệm vụ đó bởi một người quản lý. Bạn nhận thấy
có một cách để thực hiện công việc tốt hơn so với cách ban đầu. Bạn quyết định áp dụng cách của
mình và thông báo cho người quản lý. Ví dụ: class ConNguoi { void hienThi() {
System.out.println(“Tôi là con người.”); } }
class NhanVien extends ConNguoi { void hienThi() {
System.out.println(“Tôi là nhân viên.”); } } public class Main {
public static void main(String[] args) {
ConNguoi conNguoi = new NhanVien();
conNguoi.hienThi(); // In ra: “Tôi là nhân viên.” } }
Overloading (Ghi chồng)
Overloading là kỹ thuật tạo ra nhiều phương thức cùng tên nhưng khác nhau về số lượng hoặc kiểu
dữ liệu của tham số. Các phương thức được gọi tương ứng với các tham số truyền vào. Môt ví dụ thực
tế để bạn dễ hiểu hơn là máy giặt có nhiều chế độ giặt khác nhau. Máy giặt sử dụng kỹ thuật nạp chồng
(overloading) để cung cấp cho bạn nhiều tùy chọn khác nhau như giặt nhanh, giặt êm, giặt bằng nước
nóng để giặt các loại quần áo khác nhau. Ví dụ: class HinhChuNhat {
double tinhDienTich(double chieuDai, double chieuRong) { return chieuDai * chieuRong; }
double tinhDienTich(double canh) { return canh * canh; } }
Tại sao sử dụng tính đa hình trong Java?
Đa hình (Polymorphism) trong Java cho phép viết một phương thức có thể xử lý chính xác nhiều loại
chức năng khác nhau có cùng tên. Chúng ta cũng có thể đạt được tính nhất quán trong mã của mình
bằng cách sử dụng đa hình.
Ưu điểm của đa hình trong Java
Nó cung cấp khả năng tái sử dụng cho mã.Chúng ta có thể tận dụng các lớp và phương
thức đã được định nghĩa trước để triển khai các chức năng mới mà không cần viết lại
mã nguồn từ đầu. Ngoài ra, người lập trình có thể thay đổi mã mà không ảnh hưởng đến mã gốc. 
Cho phép tạo ra các lớp con có tính chất riêng của chúng và sử dụng chúng trong một
cấu trúc kế thừa phức tạp hơn. 
Với ít dòng mã hơn, người lập trình dễ dàng hơn trong việc sửa lỗi mã.
Nhược điểm của tính đa hình trong Java
Tính đa hình có thể làm tăng độ phức tạp của mã nguồn và khó hiểu hơn, đặc biệt là khi
sử dụng nhiều lớp con kế thừa từ cùng một lớp cha. 
Tính đa hình có thể làm giảm hiệu suất của chương trình trong một số trường hợp. Khi
chúng ta sử dụng đa hình, Java phải tìm kiếm phương thức thích hợp để thực thi, điều
này có thể làm giảm hiệu suất.
Tuy nhiên chúng ta vẫn có cải thiện nhược điểm của tính đa hình trong Java bằng việc sử dụng các
các thiết kế mẫu (design patterns), áp dụng các kỹ thuật và các công cụ hỗ trợ khác như Kotlin, Scala hoặc IDE như Eclipse,…
So sánh Linkedlist và Arraylist ( col ections )
Giống: cả 2 đều dùng để lưu trữ danh sách. 
ArrayList là dùng một mảng động (như mảng thường nhưng có thể thay đổi kích
thước và các phương thức thêm) để lưu trữ phần tử. 
LinkedList sử dụng danh sách liên kết để lưu trữ phần tử. Mỗi phần thử có thể được
gọi là 1 node trong danh sách. khác:
1. Cách lưu trữ phần tử: Định nghĩa đã nêu rõ rồi đúng không nào
2. ArrayList thêm và xóa phần tử chậm hơn LinkedList: Điều này khá dễ hiểu vì
LinkedList chỉ cần thay đổi luồng trỏ của các node trong danh sách nên độ phức tạp
là O(1) còn ArrayList phải tăng/lùi tất cả những vị trí sau vị trí muốn thêm/xóa nên độ phức tạp là O(n).
3. ArrayList truy xuất phần tử nhanh hơn LinkedList: ArrayList muốn truy xuất đến phân
tử thứ mấy trong danh sách thì chỉ cần gọi vị trí đó ra là được nên mất O(1) phức
tạp, còn LinkedList thì phải duyệt qua các phần tử trước đó thì mới truy xuất được
đến phần tử cần lấy nên độ phức tạp là O(n)
4. ArrayList chỉ có thể hoạt động như 1 list thông thường, còn LinkedList có thể hoạt
động như ArrayList, stack, queue. (stack và queue mình sẽ nói đến ở bài blog khác nhé)
5. ArrayList yêu cầu ít bộ nhớ hơn LinkedList: Vì ngoài lưu trữ giá trị thì các node trong
LinkedList còn phải chứa các tham chiếu đến phần tử trước, sau của nó nữa.
Như vậy mọi người có lẽ đã hiểu rõ về 2 loại danh sách thường sử dụng này.
So sánh HashSet, LinkedHashSet và TreeSet Giống:
Cả ba không cho phép các phần tử trùng lặp. 
Cả ba không được đồng bộ (non-synchronized). 
Cả ba đều cài đặt interface Cloneable v à Serializable. 
Cả ba đều là fail-fast. Bạn sẽ nhận được ConcurrentModificationException nếu chúng được sửa đổi
sau khi tạo đối tượng Iterator. Khác