Lập trình hướng đối tượng - Bài 5: Các kỹ thuật xây dựng lớp và sử dụng đối tượng
Bạn đang xem 20 trang mẫu của tài liệu "Lập trình hướng đối tượng - Bài 5: Các kỹ thuật xây dựng lớp và sử dụng đối tượng", để 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:
- lap_trinh_huong_doi_tuong_bai_5_cac_ky_thuat_xay_dung_lop_va.pdf
Nội dung text: Lập trình hướng đối tượng - Bài 5: Các kỹ thuật xây dựng lớp và sử dụng đối tượng
- Bộ môn Công nghệ Phần mềm Viện CNTT & TT Trường Đại học Bách Khoa Hà Nội LẬP TRÌNH HƯỚNG ĐỐI TƯỢNG Bài 05. Các kỹ thuật xây dựng lớp và sử dụng đối tượng
- Nội dung 1. Chồng phương thức 2. Thành viên ĐT và thành viên lớp 3. Truyền tham số cho phương thức 4. Một số lớp tiện ích trong Java 5. Ví dụ và bài tập 2
- Nội dung 1. Chồng phương thức 2. Thành viên ĐT và thành viên lớp 3. Truyền tham số cho phương thức 4. Một số lớp tiện ích trong Java 5. Ví dụ và bài tập 3
- Nhắc lại về phương thức ◼ Mỗi phương thức phải có một chữ ký riêng ◼ Chữ ký của phương thức bao gồm: ◼ Tên phương thức ◼ Số lượng các đối số và kiểu của chúng 4
- 1.1. Chồng phương thức ◼ Chồng phương thức (Method Overloading): Các phương thức trong cùng một lớp có thể trùng tên nhưng chữ ký phải khác nhau: ◼ Số lượng tham số khác nhau ◼ Nếu cùng số lượng tham số thì kiểu dữ liệu các tham số phải khác nhau ◼ Mục đích: ◼ Tên trùng nhau để mô tả bản chất công việc ◼ Thuận tiện cho lập trình vì không cần phải nhớ quá nhiều tên phương thức mà chỉ cần nhớ một tên và lựa chọn các tham số cho phù hợp. 5
- 1.1. Chồng phương thức (2) ◼ Ví dụ 1: ◼ Phương thức println() trong System.out.println() có 10 khai báo với các tham số khác nhau: boolean, char[], char, double, float, int, long, Object, String, và một không có tham số. ◼ Không cần sử dụng các tên khác nhau (chẳng hạn "printString“ hoặc "printDouble“) cho mỗi kiểu dữ liệu muốn hiển thị. 6
- 1.1. Chồng phương thức (3) ◼ Ví dụ 2: class MyDate { int year, month, day; public boolean setMonth(int m) { } public boolean setMonth(String s) { } } public class Test{ public static void main(String args[]){ MyDate d = new MyDate(); d.setMonth(9); d.setMonth(”September”); } } 7
- Một số chú ý với chồng phương thức ◼ Các phương thức chỉ được xem xét là chồng khi chúng thuộc cùng một lớp ◼ Chỉ nên sử dụng kỹ thuật này với các phương thức có cùng mục đích, chức năng; tránh lạm dụng ◼ Khi dịch, trình dịch căn cứ vào số lượng hoặc kiểu dữ liệu của tham số để quyết định gọi phương thức nào phù hợp. → Nếu không chọn được hoặc chọn được nhiều hơn 1 phương thức thì sẽ báo lỗi. 8
- Thảo luận ◼ Cho phương thức sau đây: public double test(String a, int b) ◼ Hãy chọn ra các phương thức chồng cho phương thức trên: 1. void test(String b, int a) 2. public double test(String a) 3. private int test(int b, String a) 4. private int test(String a, int b) 5. double test(double a, int b) 6. double test(int b) 7. public double test(String a, long b) 9
- Thảo luận void prt(String s) { System.out.println(s); } void f1(char x) { prt("f1(char)"); } void f1(byte x) { prt("f1(byte)"); } void f1(short x) { prt("f1(short)"); } void f1(int x) { prt("f1(int)"); } void f1(long x) { prt("f1(long)"); } void f1(float x) { prt("f1(float)"); } void f1(double x) { prt("f1(double)"); } ◼ Điều gì xảy ra nếu thực hiện: 5 → int ◼ f1(5); ◼ char x=‘a’; f1(x); ◼ byte y=0; f1(y); 10 ◼ float z = 0; f1(z);
- Thảo luận void prt(String s) { System.out.println(s); } void f2(short x) { prt("f3(short)"); } void f2(int x) { prt("f3(int)"); } void f2(long x) { prt("f5(long)"); } void f2(float x) { prt("f5(float)"); } ◼ Điều gì xảy ra nếu thực hiện: ◼ f2(5); ◼ char x=‘a’; f2(x); ◼ byte y=0; f2(y); ◼ float z = 0; f2(z); ◼ Điều gì xảy ra nếu gọi f2(5.5)? Error: cannot find symbol: method f2(double) 11
- Thảo luận ◼ Dự đoán kết quả của đoạn chương trình sau: public class Test { private void myFunction(int a, long b) { System.out.println("int long"); } private void myFunction(long a, int b) { System.out.println("long int"); } public static void main(String[] args) { Test t = new Test(); t.myFunction(3, 8); } } 12
- 1.2. Chồng phương thức khởi tạo ◼ Trong nhiều tình huống khác nhau cần khởi tạo đối tượng theo nhiều cách khác nhau ◼ → Cần xây dựng các phương thức khởi tạo khác nhau cho đối tượng theo nguyên lý chồng phương thức (constructor overloading). 13
- Ví dụ public class BankAccount{ private String owner; private double balance; public BankAccount(){owner = “noname”;} public BankAccount(String o, double b){ owner = o; balance = b; } } public class Test{ public static void main(String args[]){ BankAccount acc1 = new BankAccount(); BankAccount acc2 = new BankAccount(“Thuy”, 100); } } 14
- Thảo luận ◼ Dự đoán kết quả của đoạn chương trình sau: public class Test { private Test(Object o) { System.out.println("Object"); } private Test(double[] d) { System.out.println("Double array"); } public static void main(String[] args) { new Test(null); } } 15
- Thảo luận: nạp chồng phương thức main()? ◼ Hoàn toàn có thể nạp chồng phương thức main! ◼ JVM luôn luôn tìm và gọi "the original main method" khi thực thi chương trình public class Helloworld { public static void main(String[] args) { System.out.println("main(String[] args) method"); } public static void main(Integer[] args){ System.out.println("main(Integer[] args) method"); } public static void main(Double[] args){ System.out.println("main(Double[] args) method"); } } 16
- Thảo luận: nạp chồng phương thức main()? ◼ Kết quả khi biên dịch và thực thi chương trình sau? public class Test { public static void main(String[] args) { System.out.println("Hi Man (from main)"); Test.main("Man"); } public static void main(String arg1) { System.out.println("Hi, " + arg1); Test.main("Dear Man", "My Man"); } public static void main(String arg1, String arg2) { System.out.println("Hi, " + arg1 + ", " + arg2); } } 17
- 1.3. Từ khóa this ◼ Nhắc lại: Tự tham chiếu đến đối tượng hiện tại, sử dụng bên trong lớp tương ứng với đối tượng muốn tham chiếu. ◼ Sử dụng thuộc tính hoặc phương thức của đối tượng thông qua toán tử “.”, ví dụ: public class BankAccount{ private String owner; public void setOwner(String owner){ this.owner = owner; } public BankAccount() { this.setOwner(“noname”); } } ◼ Gọi đến phương thức khởi tạo khác của lớp: ◼ this(danh_sach_tham_so); //neu co tham so 18
- Ví dụ public class Ship { private double x=0.0, y=0.0 private double speed=1.0, direction=0.0; public String name; public Ship(String name) { this.name = name; } public Ship(String name, double x, double y) { this(name); this.x = x; this.y = y; } public Ship(String name, double x, double y, double speed, double direction) { this(name, x, y); this.speed = speed; this.direction = direction; } //continue 19
- //(cont.) private double degreeToRadian(double degrees) { return(degrees * Math.PI / 180.0); } public void move() { move(1); } public void move(int steps) { double angle = degreesToRadians(direction); x = x + (double)steps*speed*Math.cos(angle); y = y + (double)steps*speed*Math.sin(angle); } public void printLocation() { System.out.println(name + " is at (" + x + "," + y + ")."); } } //end of Ship class 20
- Nội dung 1. Chồng phương thức 2. Thành viên ĐT và thành viên lớp 3. Truyền tham số cho phương thức 4. Một số lớp tiện ích trong Java 5. Ví dụ và bài tập 22
- 2.1. Thành viên static ◼ Trong Java ◼ Các thành viên bình thường là thành viên thuộc về đối tượng ◼ Thành viên thuộc về lớp được khai báo là static ◼ Cú pháp khai báo thành viên static: chi_dinh_truy_cap static kieu_du_lieu tenBien; ◼ Ví dụ: 23
- Ví dụ lớp JOptionPane trong javax.swing ◼ Thuộc tính ◼ Phương thức: 24
- Ví dụ - sử dụng thuộc tính và phương thức static lớp JOptionPane JOptionPane.showMessageDialog(null,"Ban da thao tac loi", "Thong bao loi", JOptionPane.ERROR_MESSAGE); JOptionPane.showConfirmDialog(null,"Ban co chac chan muon thoat?", "Hay lua chon", JOptionPane.YES_NO_OPTION); 25
- Ví dụ - sử dụng thuộc tính và phương thức static lớp JOptionPane (2) ◼ Object[] options = { "OK", "CANCEL" }; ◼ JOptionPane.showOptionDialog(null,“Nhan OK de tiep tuc", "Canh bao", JOptionPane.DEFAULT_OPTION, JOptionPane.WARNING_MESSAGE,null,option s,options[0]); 26
- 2.1. Thành viên static (2) ◼ Thay đổi giá trị của một thành viên static trong một đối tượng của lớp sẽ thay đổi giá trị của thành viên này của tất cả các đối tượng khác của lớp đó. ◼ Các phương thức static chỉ có thể truy cập vào các thuộc tính static và chỉ có thể gọi các phương thức static trong cùng lớp. 27
- Ví dụ 1 class TestStatic{ public static int iStatic; public int iNonStatic; } public class TestS { public static void main(String[] args) { TestStatic obj1 = new TestStatic(); obj1.iStatic = 10; obj1.iNonStatic = 11; System.out.println(obj1.iStatic + ”,” + obj1.iNonStatic); TestStatic obj2 = new TestStatic(); System.out.println(obj2.iStatic + ”,” + obj2.iNonStatic); obj2.iStatic = 12; System.out.println(obj1.iStatic + ”,” + obj1.iNonStatic); } } 28
- Ví dụ 2 public class Demo { int i = 0; void tang(){ i++; } public static void main(String[] args) { tang(); System.out.println("Gia tri cua i la" + i); } } non-static method tang() cannot be referenced from a static contex non-static variable i cannot be referenced from a static context 29
- 2.1. Thành viên static ◼ static có thể áp dụng cho: ◼ blocks ◼ variables ◼ methods ◼ nested classes 30
- 2.2. Thành viên hằng ◼ Một thuộc tính/phương thức không thể thay đổi giá trị/nội dung trong quá trình sử dụng. ◼ Cú pháp khai báo: chi_dinh_truy_cap final kieu_du_lieu TEN_HANG = gia_tri; ◼ Ví dụ: final double PI = 3.141592653589793; public final int VAL_THREE = 39; private final int[] A = { 1, 2, 3, 4, 5, 6 }; 31
- 2.2. Thành viên hằng (2) ◼ Thông thường các hằng số liên quan đến lớp được khai báo là static final nhằm giúp truy cập dễ dàng 32
- Instance member vs. Class member Thành viên đối tượng Thành viên lớp ◼ Thuộc tính/phương thức ◼ Thuộc tính/phương thức chỉ được truy cập thông có thể được truy cập qua đối tượng thông qua lớp ◼ Mỗi đối tượng có 1 bản ◼ Các đối tượng có chung sao riêng của 1 thuộc 1 bản sao của 1 thuộc tính đối tượng tính lớp ◼ Giá trị của 1 thuộc tính ◼ Giá trị của 1 thuộc tính đối tượng của các đối lớp của các đối tượng tượng khác nhau là khác nhau là giống khác nhau. nhau. 33
- Nội dung 1. Chồng phương thức 2. Thành viên ĐT và thành viên lớp 3. Truyền tham số cho phương thức 4. Một số lớp tiện ích trong Java 5. Ví dụ và bài tập 34
- 3. Truyền tham số cho phương thức ◼ Có thể sử dụng bất kỳ kiểu dữ liệu nào cho tham số của phương thức hoặc constructor ◼ Kiểu dữ liệu nguyên thủy ◼ Kiểu dữ liệu tham chiếu: mảng và đối tượng ◼ Ví dụ public Polygon polygonFrom(Point[] corners) { // method body goes here } 35
- 3. Truyền tham số cho phương thức (2) ◼ Java truyền mọi tham số cho phương thức dưới dạng giá trị (pass-by-value): Truyền giá trị/bản sao của tham số thực ◼ Với tham số có kiểu dữ liệu tham trị (kiểu dữ liệu nguyên thủy): Truyền giá trị/bản sao của các biến nguyên thủy truyền vào ◼ Với tham số có kiểu dữ liệu tham chiếu (mảng và đối tượng): Truyền giá trị/bản sao của tham chiếu gốc truyền vào → Thay đổi tham số hình thức không làm ảnh hưởng đến tham số thực 36
- 3.1. Với kiểu dữ liệu tham trị ◼ Các giá trị nguyên thủy không thể thay đổi khi truyền như một tham số ◼ Phương thức swap này có hoạt động đúng không? public void swap(int var1, int var2) { int temp = var1; var1 = var2; var2 = temp; } 37
- 3.2. Với kiểu dữ liệu tham chiếu ◼ Thực ra là truyền bản sao của tham chiếu gốc, chứ không phải truyền tham chiếu gốc hoặc truyền đối tượng (pass the references by value, not the original reference or the object) ◼ Sau khi truyền cho phương thức, đối tượng có ít nhất 2 tham chiếu 38
- 3.2. Với kiểu dữ liệu tham chiếu-ví dụ 1 public class Student { private int year; private String name; public Student(String name, int year) { this.year = year; this.name = name; } public int getYear() { return year; } public void setYear(int year) { this.year = year; } } 39
- 3.2. Với kiểu dữ liệu tham chiếu-ví dụ 1 public class Test { public static void change(Student std){ std.setYear(2000); } public static void main(String[] args) { Student std = new Student("Nam", 1990); System.out.println(std.getYear()); change(std); System.out.println(std.getYear()); } } 40
- 4.2. Với kiểu dữ liệu tham chiếu-ví dụ 2 public class Test { public static void change(Student std){ std = new Student("Hung", 1995); } public static void main(String[] args) { Student std = new Student("Nam", 1990); System.out.println(std.getYear()); change(std); System.out.println(std.getYear()); } } 41
- Ví dụ public class Point { private double x; private double y; public Point() { } public Point(double x, double y) { this.x = x; this.y = y; } public void setX(double x) { this.x = x; } public void setY(double y) { this.y = y; } public void printPoint() { System.out.println("X: " + x + " Y: " + y); } } 42
- public class Test { public static void tricky(Point arg1, Point arg2) { arg1.setX(100); arg1.setY(100); Point temp = arg1; arg1 = arg2; arg2 = temp; } public static void main(String [] args) { Point pnt1 = new Point(0,0); Point pnt2 = new Point(0,0); pnt1.printPoint(); pnt2.printPoint(); System.out.println(); tricky(pnt1, pnt2); pnt1.printPoint(); pnt2.printPoint(); } } 43
- ◼ Chỉ có các tham chiếu của phương thức được tráo đổi, chứ không phải các tham chiếu gốc 44
- 3.3. Truyền số lượng tham số tùy ý ◼ Được gọi là varargs. Cú pháp: ◼ ten_phuong_thuc(Kieu_dl ten_tham_so) ◼ Ví dụ 1: ◼ Khai báo: public PrintStream printf(String format, Object args) ◼ Sử dụng ◼ System.out.printf ("%s: %d, %s\n", name, idnum, address); ◼ System.out.printf ("%s: %d, %s, %s, %s\n", name, idnum, address, phone, email); 45
- ◼ Ví dụ 2 public Polygon polygonFrom(Point corners) { int numberOfSides = corners.length; double squareOfSide1, lengthOfSide1; squareOfSide1 = (corners[1].x - corners[0].x) *(corners[1].x - corners[0].x) + (corners[1].y - corners[0].y) *(corners[1].y - corners[0].y) ; lengthOfSide1 = Math.sqrt(squareOfSide1); //create & return a polygon connecting the Points } ◼ Nhận xét ◼ corners được coi như một mảng ◼ Phương thức có thể được gọi bằng cách truyền một mảng hoặc một loạt các tham số truyền vào 46
- Bài tập: Tính tổng số lượng các số nguyên bất kỳ public class Test { public static int plus(int arr) { int result = 0; for (int i : arr) { result += i; } return result; } public static void main(String[] args) { System.out.println(plus(1, 2, 3, 4, 5)); } } 47
- Nội dung 1. Chồng phương thức 2. Thành viên ĐT và thành viên lớp 3. Truyền tham số cho phương thức 4. Một số lớp tiện ích trong Java 5. Ví dụ và bài tập 48
- 4.1. Package trong Java ◼ Package giống như thư mục giúp: ◼ Tổ chức và xác định vị trí lớp dễ dàng và sử dụng các lớp một cách phù hợp. ◼ Tránh cho việc đặt tên lớp bị xung đột (trùng tên) ◼ Các package khác nhau có thể chứa các lớp có cùng tên ◼ Bảo vệ các lớp, dữ liệu và phương thức ở mức rộng hơn so với mối quan hệ giữa các lớp. ◼ Một package cũng có thể chứa các package khác 49
- 4.1. Package trong Java (2) ◼ Tên đầy đủ của lớp bao gồm tên gói và tên lớp: 50
- a. Tham chiếu giữa các lớp ◼ Trong cùng 1 package: Sử dụng tên lớp ◼ Khác package: Phải cung cấp tên đầy đủ cho các lớp được định nghĩa trong package khác. ◼ Ví dụ: public class HelloNameDialog { public static void main(String[] args){ String result; result = javax.swing.JOptionPane. showInputDialog("Hay nhap ten ban:"); javax.swing.JOptionPane.showMessageDialog (null, "Xin chao "+ result + "!"); } } 51
- a. Tham chiếu giữa các lớp (2) ◼ Lệnh import: ◼ Sử dụng lệnh import để khai báo các package hoặc các lớp để khi sử dụng không cần nêu tên đầy đủ. ◼ Ví dụ: import javax.swing.JOptionPane; public class HelloNameDialog { public static void main(String[] args){ String result; result = JOptionPane.showInputDialog("Hay nhap ten ban:"); JOptionPane.showMessageDialog (null, "Xin chao "+ result + "!"); } } 52
- b. Các package trong Java •java.applet •javax.rmi •java.awt •javax.security •java.beans •javax.sound •java.io •javax.sql •java.lang •javax.swing •java.math •javax.transaction •java.net •javax.xml •java.nio •org.ietf.jgss •java.rmi •org.omg.CORBA •java.security •org.omg.CosNaming •java.sql •org.omg.Dynamic •java.text •org.omg.IOP •java.util •org.omg.Messaging •javax.accessibility •org.omg.PortableInterceptor •javax.crypto •org.omg.PortableServer •javax.imageio •org.omg.SendingContext •javax.naming •org.omg.stub.java.rmi •javax.net •org.w3c.dom •javax.print •org.xml 53
- b. Các package trong Java (2) ◼ Các package cơ bản trong Java ◼ java.lang ◼ Cung cấp các lớp cơ bản cho thiết kế ngôn ngữ lập trình Java ◼ Bao gồm wrapper classes, String và StringBuffer, Object, ◼ Import ngầm định vào tất cả các lớp ◼ java.util ◼ Bao gồm tập hợp framework, mô hình sự kiện, date time, và nhiều tiện ích khác. ◼ java.io ◼ Cung cấp khả năng vào/ra hệ thống với các luồng dữ liệu và hệ thống file. 54
- b. Các package trong Java (3) ◼ Các package cơ bản trong Java ◼ java.math ◼ Cung cấp các lớp thực thi các phép toán với số nguyên và các phép toán thập phân ◼ java.sql ◼ Cung cấp các API cho phép truy nhập và xử lý dữ liệu được lưu trữ trong một nguồn dữ liệu (thường sử dụng cơ sở dữ liệu quan hệ) ◼ javax.swing ◼ Cung cấp các lớp và giao diện cho phép tạo ra các ứng dụng đồ họa. ◼ 55
- 4.2. Các lớp bao (Wrapper class) ◼ Các kiểu dữ liệu nguyên thủy không có các phương thức liên quan đến nó. ◼ Mỗi kiểu dữ liệu nguyên thủy có một lớp tương ứng gọi là lớp bao: ◼ Các lớp bao sẽ “gói” dữ liệu nguyên thủy và cung cấp các phương thức thích hợp cho dữ liệu đó. ◼ Mỗi đối tượng của lớp bao đơn giản là lưu trữ một biến đơn và đưa ra các phương thức để xử lý nó. ◼ Các lớp bao là một phần của Java API 56
- 4.2. Các lớp bao (2) 57
- a. Chuyển đổi kiểu dữ liệu ◼ Sử dụng toString() để chuyển các giá trị số thành xâu. ◼ Sử dụng Value() để chuyển từ đối tượng của lớp bao thành giá trị nguyên thủy của đối tượng tương ứng Float objF = new Float(“4.67”); float f = objF.floatValue(); // f=4.67F int i = objF.intValue(); //i=4 ◼ Sử dụng parse () và valueOf() để chuyển xâu thành các giá trị số. int i = Integer.parseInt(“123”); //i=123 double d = Double.parseDouble(“1.5”) ; // d=1.5 Double objF2 = Double.valueOf(“-36.12”); long l = objF2.longValue(); // l=-36L 58
- a. Chuyển đổi kiểu dữ liệu (2) 59
- b. Các hằng số ◼ Boolean ◼ Float ◼ Boolean FALSE ◼ float MAX_VALUE ◼ Boolean TRUE ◼ float MIN_VALUE ◼ Byte ◼ float NaN ◼ byte MIN_VALUE ◼ float NEGATIVE_INFINITY ◼ byte MAX_VALUE ◼ float POSITIVE_INFINITY ◼ Character ◼ Integer ◼ int MAX_RADIX ◼ int MIN_VALUE ◼ char MAX_VALUE ◼ int MAX_VALUE ◼ int MIN_RADIX ◼ Long ◼ char MIN_VALUE ◼ long MIN_VALUE ◼ Unicode classification constants ◼ long MAX_VALUE ◼ Double ◼ Short ◼ double MAX_VALUE ◼ short MIN_VALUE ◼ double MIN_VALUE ◼ short MAX_VALUE ◼ double NaN ◼ double NEGATIVE_INFINITY ◼ double POSITIVE_INFINITY 60
- Ví dụ double d = (new Integer(Integer.MAX_VALUE)). doubleValue(); System.out.println(d); // 2.147483647E9 String input = "test 1-2-3"; int output = 0; for (int index=0;index<input.length();index++) { char c = input.charAt(index); if (Character.isDigit(c)) output = output * 10 + Character.digit(c, 10); } System.out.println(output); // 123 61
- Quiz 1 ◼ Lựa chọn nào là các lớp bao (wrapper class): a. java.lang.Void b. java.lang.Int c. java.lang.Boolean d. java.lang.Long e. java.lang.String 62
- 4.3. Xâu (String) ◼ Kiểu String là một lớp và không phải là kiểu dữ liệu nguyên thủy ◼ Một String được tạo thành từ một dãy các ký tự nằm trong dấu nháy kép: String a = "A String"; String b = ""; ◼ Đối tượng String có thể khởi tạo theo nhiều cách: String c = new String(); String d = new String("Another String"); String e = String.valueOf(1.23); String f = null; 63
- a. Ghép xâu ◼ Toán tử + có thể nối các String: String a = "This" + " is a " + "String"; //a = “This is a String” ◼ Các kiểu dữ liệu cơ bản sử dụng trong lời gọi println() được chuyển đổi tự động sang kiểu String System.out.println("answer = " + 1 + 2 + 3); System.out.println("answer = " + (1+2+3)); → Hai câu lệnh trên có in ra cùng một kết quả? 64
- b. Các phương thức của xâu String name = "Joe Smith"; name.toLowerCase(); // "joe smith" name.toUpperCase(); // "JOE SMITH" "Joe Smith ".trim(); // "Joe Smith" "Joe Smith".indexOf('e'); // 2 "Joe Smith".length(); // 9 "Joe Smith".charAt(5); // 'm' "Joe Smith".substring(5); // "mith" "Joe Smith".substring(2,5); // "e S" 65
- c. So sánh hai xâu ◼ oneString.equals(anotherString) ◼ Kiểm tra tính tương đương String name = "Joe"; ◼ Trả về true hoặc false if ("Joe".equals(name)) name += " Smith"; ◼ oneString.equalsIgnoreCase(anotherString) ◼ Kiểm tra KHÔNG xét đến ký tự hoa, thường boolean same = "Joe".equalsIgnoreCase("joe"); ◼ So sánh oneString == anotherString sẽ gây nhập nhằng ◼ So sánh 2 đối tượng 66
- c. So sánh hai xâu (2) String s1 = new String(“Hello”); s1 String s2 = s1; Hello (s1==s2) trả về true s2 String s1 = new String(“Hello”); String s2 = new String(“Hello”); (s1==s2) trả về false s1 Hello s2 Hello 67
- c. So sánh hai xâu ◼ oneString.compareTo(anotherString) ◼ So sánh một xâu với một đối tượng khác, so sánh theo thứ tự từ điển (lexicographically) ◼ int compareTo(Object o) ◼ Giá trị trả về: ◼ Giá trị = 0: 2 xâu có thứ tự tương đương ◼ Giá trị xâu hiện tại ◼ Giá trị > 0: tham số có thứ tự < xâu hiện tại String str1 = "Strings"; String str2 = new String("Strings"); String str3 = new String("Integers"); int result = str1.compareTo( str2 ); result = str2.compareTo( str3 ); 68
- d. Điểm đặc biệt của String ◼ Khởi tạo String theo 2 cách: ◼ Gán 1 giá trị literal ◼ Dùng toán tử new (Không khuyến khích dùng) ◼ Ví dụ: ◼ String str1 = "Java is Hot"; // Implicit construction qua string literal ◼ str1 is được khai báo là 1 String reference và được khởi tạo 1 giá trị String literal "Java is Hot" ◼ String str2 = new String("I'm cool"); // Explicit construction qua toán tử new ◼ str2 được khai báo là 1 String reference và được khởi tạo qua toán tử new. ◼ String literals được chứa trong 1common pool. ◼ → Cho phép chia sẻ lưu trữ các String với cùng nội dung để tiết kiệm bộ nhớ. ◼ String objects lưu trữ giá trị trong heap, không tiết kiệm được bộ nhớ 69
- String Literal vs. String Object ◼ String s1 = "Hello"; // String literal ◼ String s2 = "Hello"; // String literal ◼ String s3 = s1; // same reference ◼ String s4 = new String("Hello"); // String object ◼ String s5 = new String("Hello"); // String object 70
- d. Điểm đặc biệt của String (2) String s1 = new String("test"); String s2 = "test"; String s3 = String.valueOf("test"); System.out.println(s1==s2); System.out.println(s1==s3); System.out.println(s2==s3); String s4 = new String("test"); String s5 = "test"; String s6 = String.valueOf("test"); System.out.println(s1==s4); System.out.println(s2==s5); System.out.println(s3==s6); 71
- Quiz 2 ◼ Biểu thức nào là không hợp lệ: a."co".concat("ol") b.("co" + "ol") c.('c' + 'o' + 'o' + 'l') d.("co" + new String('o' + 'l')) e.("co" + new String("co")) 72
- 4.4. StringBuffer ◼ String là kiểu bất biến: ◼ Đối tượng không thay đổi giá trị sau khi được tạo ra → Các xâu của lớp String được thiết kế để không thay đổi giá trị. ◼ Khi các xâu được ghép nối với nhau một đối tượng mới được tạo ra để lưu trữ kết quả → Ghép nối xâu thông thường rất tốn kém về bộ nhớ. ◼ StringBuffer là kiểu biến đổi: ◼ Đối tượng có thể thay đổi giá trị sau khi được tạo ra 73
- StringBuffer & StringBuilder ◼ StringBuffer: Khi nội dung của xâu sẽ thay đổi. Có thể có nhiều thread truy cập đến nội dung của xâu (threadsafe). Hạn chế tốc độ chậm. ◼ StringBuilder: (Chỉ từ Java 1.5 mới có lớp này): Khi nội dung của xâu sẽ thay đổi. Chỉ có 1 thread truy cập đến nội dung của xâu (Not threadsafe). Bù lại, tốc độ nhanh. 74
- 4.4. StringBuffer (2) ◼ String s = new String(“hello”); String t = s; s = new String(“goodbye”); 75
- 4.4. StringBuffer (3) ◼ StringBuffer: ◼ Cung cấp các đối tượng xâu có thể thay đổi giá trị → Sử dụng StringBuffer khi: ◼ Dự đoán các ký tự trong xâu có thể thay đổi. ◼ Khi xử lý các xâu một cách linh động, ví dụ như đọc dữ liệu text từ một tệp tin. ◼ Cung cấp các cơ chế hiệu quả hơn cho việc xây dựng, ghép nối các xâu: ◼ Việc ghép nối xâu thường được các trình biên dịch chuyển sang thực thi trong lớp StringBuffer 76
- 4.4. StringBuffer (4) ◼ Tính biến đổi: Nếu một đối tượng bị biến đổi, thì tất cả các quan hệ với đối tượng sẽ nhận giá trị mới. 77
- 4.4. StringBuffer (5) ◼ Nếu tạo xâu thông qua vòng lặp thì sử dụng StringBuffer StringBuffer buffer = new StringBuffer(15); buffer.append("This is ") ; buffer.append("String") ; buffer.insert(7," a") ; buffer.append('.'); System.out.println(buffer.length()); // 17 System.out.println(buffer.capacity()); // 32 String output = buffer.toString() ; System.out.println(output); // "This is a String." 78
- 4.5. Lớp Math ◼ java.lang.Math cung cấp các thành phần static: ◼ Các hằng toán học: ◼ Math.E ◼ Math.PI ◼ Các hàm toán học: ◼ max, min ◼ abs, floor, ceil ◼ sqrt, pow, log, exp ◼ cos, sin, tan, acos, asin, atan ◼ random 79
- 4.5. Lớp Math (2) ◼ Hầu hết các hàm nhận tham số kiểu double và giá trị trả về cũng có kiểu double ◼ Ví dụ : Math.pow(Math.E, Math.sqrt(2.0*Math.PI)) Hoặc: Math.exp(Math.sqrt(2.0*Math.PI)) 80
- 4.6. Lớp System ◼ java.lang.System chứa nhiều hàm tiện ích hữu dụng ◼ Kiểm soát vào ra (I/O) chuẩn ◼ Các luồng InputStream in, PrintStreams out và err là các thuộc tính của lớp System. ◼ Có thể thiết lập lại nhờ các hàm setIn(), setOut() và setErr() ◼ arraycopy(): Sao chép mảng hoặc tập con với hiệu năng cao.
- 4.6. Lớp System (2) ◼ currentTimeMillis(): Trả về thời gian hiện tại theo millisecond ◼ exit(): Kết thúc hoạt động của Java Virtual Machine ◼ gc(): Yêu cầu bộ thu gom rác hoạt động ◼ Các phương thức liên quan đến thuộc tính của hệ thống: Lấy các thông tin thuộc tính như phiên bản của Java Runtime Environment version, thư mục cài đặt Java,
- 4.6. Lớp System (3) import java.util.Properties; public class PropertiesTest { public static void main(String[] args) { System.out.println(System.getProperty("path.separator")); System.out.println(System.getProperty("file.separator")); System.out.println(System.getProperty("java.class.path")); System.out.println(System.getProperty("os.name")); System.out.println(System.getProperty("os.version")); System.out.println(System.getProperty("user.dir")); System.out.println(System.getProperty("user.home")); System.out.println(System.getProperty("user.name")); } }
- 4.6. Lớp System (4)
- 4.7. Lớp Random ◼ Sử dụng lớp này để tạo ra số ngẫu nhiên ◼ Thường dùng để tạo ra số ngẫu nhiên tùy ý, hoặc không theo trình tự ◼ Hai hàm khởi tạo của lớp này ◼ Hàm khởi tạo có 1 tham số là hạt giống để tạo số ngẫu nhiên ◼ Dùng giá trị này để bắt đầu tạo số ngẫu nhiên ◼ Hàm khởi tạo không có tham số ◼ Sử dụng đồng hồ hệ thống hiện hành để tạo số ngẫu nhiên
- 4.7. Lớp Random ◼ Ví dụ: import java.util.Random; Random rand = new Random(); int n = rand.nextInt(50) + 1;
- Nội dung 1. Chồng phương thức 2. Thành viên ĐT và thành viên lớp 3. Truyền tham số cho phương thức 4. Một số lớp tiện ích trong Java 5. Ví dụ và bài tập 87
- Bài tập 1 ◼ Tiếp bài tập 2 của bài học trước, sử dụng thành viên lớp để cài đặt đếm số đối tượng của lớp NhanVien được tạo ra tại bất kỳ thời điểm nào, ở bất kỳ đâu. Cài đặt minh họa cách thức sử dụng. 88
- Bài tập 2 ◼ Cài đặt phương thức, đầu vào là số lượng bất kỳ các đối tượng lớp NhanVien, đầu ra là tổng lương của các đối tượng này. 89
- Bài tập 3 ◼ Sử dụng lớp System đếm thời gian phép cộng xâu nhiều lần với String, và dùng phương thức append với StringBuffer để so sánh hiệu năng. 90