Friday, August 14, 2015

Bài 11 - String class , Array List và Vector (tiếp)

Tiếp tục loạt bài hướng dẫn tiếp theo về ArrayList và Vector.
III. Cách sử dụng ArrayList và Vector
1. ArrayList.
Như các bạn đã trải qua loạt bài hướng dẫn về cách sử dụng mảng (array) . Thì ArrayList là một công cụ rất mạnh về mảng . Nó khác với mảng các bạn đã tìm hiểu ở chỗ nào . Đó chính là ArrayList là một mảng động . Nó có thể co dãn kích thước mảng mà không cần phải khai báo fix cứng size như ban đầu.
Cách khai báo ArrayList như sau :
ArrayList<Object> nameList = new ArrayList<Object>();
Sau đây là các method cung cấp cho ArrayList().
Các bạn có thể tìm hiểu cách sử dụng ArrayList từ bảng này . Hoặc cũng có thể làm các ví dụ để có thể kiểm chứng được cách sử dụng ArrayList.  Một khi các bạn đã sử dụng quen , thì mình tin chắc là các bạn sẽ quên thích cách dùng mảng ngày :P
Ví dụ 1:
 package nosoft.com.demoarrayList;  
 import java.util.ArrayList;  
 public class DemoArrayList {  
  public static void main(String[] args) {  
  ArrayList listHS = new ArrayList(); // create new ArrayList  
  String ten1 = "Tran Van A"; // create object  
  listHS.add(ten1); // add item into listHS  
  String ten2 = "Nguyen Cao C";  
  listHS.add(ten2);  
  String ten3 = "Dinh Tien F";  
  listHS.add(ten3);  
  String ten4 = "Van Dai G";  
  listHS.add(ten4);  
  // add four element  
  // start arraylist is element zero (0)  
  for (int i = 0; i < listHS.size(); i++) { // listHS.size() return size  
        // with arraylist  
   System.out.println(listHS.get(i)); // get element from index  
  }  
  String tenChen = "Nguyen Van Chen";  
  listHS.add(2, tenChen); // insert into index 2  
  System.out.println("\nDanh sách sau khi bị chèn thêm: ");  
  for (int i = 0; i < listHS.size(); i++) {  
   System.out.println(listHS.get(i));  
  }  
  // edit 1 object , use index of arraylist  
  System.out.println("\nDanh sách sau khi bị sửa giá trị 1 đối tượng: ");  
  String tenSet = "Hoang Van Set";  
  listHS.set(3, tenSet); // changed postion 3  
  for (int i = 0; i < listHS.size(); i++) {  
   System.out.println(listHS.get(i));  
  }  
  // delete 1 element in arraylist  
  System.out.println("\nPhần tử thứ 1 đã bị xóa đi");  
  listHS.remove(1);  
  for (int i = 0; i < listHS.size(); i++) {  
   System.out.println(listHS.get(i));  
  }  
  //delete all element in arraylist  
  System.out.println("Xóa toàn bộ các phần tử ArrayList");  
  listHS.clear();  
  for (int i = 0; i < listHS.size(); i++) {  
   System.out.println(listHS.get(i));  
  } // Null all  
  }  
 }  



Ví dụ 2 : Sắp sếp các phần tử trong ArrayList.
 package nosoft.com.demoarrayList;  
 public class SinhVien {  
  public String hoTen;  
  public int diem;  
 }  
 //Săp xếp list sinh viên  
 package nosoft.com.demoarrayList;  
 import java.util.ArrayList;  
 import java.util.Collections;  
 import java.util.Comparator;  
 import java.util.Scanner;  
 public class SortArrayList {  
  public static void main(String[] args) {  
     Scanner input = new Scanner(System.in);  
     System.out.println("Nhập số sinh viên: ");  
     int n = input.nextInt();  
     ArrayList<SinhVien> listSinhVien = new ArrayList();  
     for (int i = 0; i < n; i++) {  
       input.nextLine();  
       SinhVien sv = new SinhVien();  
       System.out.println("Thông tin sinh viên thứ " + i);  
       System.out.print("Họ và Tên: ");  
       sv.hoTen = input.nextLine();  
       System.out.print("Điểm: ");  
       sv.diem = input.nextInt();  
       listSinhVien.add(sv);  
     }  
     //Sort SinhVien ==>  
     Collections.sort(listSinhVien, new Comparator<SinhVien>() {  
       @Override  
       public int compare(SinhVien sv1, SinhVien sv2) {  
         if (sv1.diem < sv2.diem) {  
           return 1;  
         } else {  
           if (sv1.diem == sv2.diem) {  
             return 0;  
           } else {  
             return -1;  
           }  
         }  
       }  
     });  
     System.out.println("Danh sách sắp xếp theo thứ tự điểm giảm dần là: ");  
     for (int i = 0; i < listSinhVien.size(); i++) {  
       System.out.println("Tên: " + listSinhVien.get(i).hoTen + " Điểm: " + listSinhVien.get(i).diem);  
     }  
   }  
 }  


Các bạn có thể tham khảo thêm cách này để sort ArrayList : here (file SortArrayList2)
Hoặc các bạn có thể tham khảo thêm tài liệu tại : here
2. Vector.
Cũng giống với ArrayList . Vector cũng là một dạng mảng động. 
Cách khai báo:
}Vector vector = new Vector()
Hoặc 
Vector<Object> vector = new Vector<>();
Các method được sử dụng trong vector.
Ví dụ :
 package nosoft.com.vector;  
 import java.util.Enumeration;  
 import java.util.Vector;  
 public class DemoVector {  
  public static void main(String args[]) {  
  // initial capacity is 3, increment is 2  
  Vector vector = new Vector(3, 2);  
  System.out.println("Initial size: " + vector.size());  
  System.out.println("Initial capacity: " + vector.capacity());  
  //add element into Vector  
  vector.addElement(new Integer(1));  
  vector.addElement(new Integer(2));  
  vector.addElement(new Integer(3));  
  vector.addElement(new Integer(4));  
  System.out.println("Capacity after four additions: "  
   + vector.capacity());  
  vector.addElement(new Double(5.45));  
  System.out.println("Current capacity: " + vector.capacity());  
  vector.addElement(new Double(6.08));  
  vector.addElement(new Integer(7));  
  System.out.println("Current capacity: " + vector.capacity());  
  //remove element in 1 index  
  vector.remove(1);   
  vector.addElement(new Float(9.4));  
  vector.addElement(new Integer(10));  
  System.out.println("Current capacity: " + vector.capacity());  
  vector.addElement(new Integer(11));  
  vector.addElement(new Integer(12));  
  System.out.println("First element: " + (Integer) vector.firstElement());  
  System.out.println("Last element: " + (Integer) vector.lastElement());  
  if (vector.contains(new Integer(3)))  
   System.out.println("Vector contains 3.");  
  // enumerate the elements in the vector.  
  Enumeration vEnum = vector.elements();  
  System.out.println("\nElements in vector:");  
  while (vEnum.hasMoreElements())  
   System.out.print(vEnum.nextElement() + " ");  
  System.out.println();  
  }  
 }  



Sau đây là bài tập cho các bạn :D
Bài tập 1:
Một số được gọi là số
thuận nghịch độc nếu ta đọc từ trái sang phải hay từ phải sang trái số đó ta
vẫn nhận được một số giống nhau. Hãy liệt kê tất cả các số thuận nghịch độc có
sáu chữ số (Ví dụ số: 558855).
Bài 2 :
Viết chương trình liệt kê các số nguyên có từ 5 đến 7 chữ số thoả mãn:
- Là số nguyên tố.
- Là số thuận nghịch.
- Mỗi chữ số đều là số nguyên tố
Source code tham khảo : here
Bài 3 : Làm lại bài tập trong bài hướng dấn 10 . Theo vector

Bài 11 - String class , Array List và Vector

OK như vậy là chúng ta đã đi qua 10 bài hướng dẫn trong loạt tutorial này .
Hôm nay mình sẽ giới thiệu cho các bạn thêm kiến thức về String class , trong bài 4 mình chưa hướng dẫn .
Và cách sử dụng mảng động Array List và Vector.
I.String class
String thuộc lớp java.lang.String , là một lớp model phạm vi sử dụng của các charactor tạo thành chuỗi. Các method được cung cấp trong lớp này đó là :
* Bạn có thể tạo mới một chuỗi String bằng cách .
String newString = new String(stringLiteral);// gọi tới contructors
String message = new String("Welcome to Java"); // gọi contructors có tham số
char[] charArray = {'G', 'o', 'o', 'd', ' ', 'D', 'a', 'y'};// khai báo từ mảng char
String message = new String(charArray);
Khi khai báo một chuỗi String kiểu này thì nó sẽ tạo ra trên bộ nhớ vật lý một vùng nhớ để lưu dữ . Và vùng nhớ này không thay đổi được dữ liệu nữa.
Nên nếu bạn thực hiện cộng chuỗi thì nó sẽ tạo ra một ô nhớ khác , chưa giá trị vừa cộng .
Ví dụ :tạo 2 chuỗi String
String s = "Java";
s = "HTML";
Tương tự như vậy , nếu các chuỗi giống nhau sẽ trỏ tới 1 vùng nhớ chứa giá trị chuỗi đó.
* So sánh chuỗi:
Có các cách so sánh chuỗi như sau :
if (string1 == string2)// dùng toán tử ==
  System.out.println("string1 and string2 are the same object");
else
  System.out.println("string1 and string2 are different objects");
Dùng method equals()
if (string1.equals(string2))
  System.out.println("string1 and string2 have the same contents");
else
  System.out.println("string1 and string2 are not equal");
Dùng method compareTo()
s1.compareTo(s2)
* Lấy độ dài của chuỗi và trích dẫn ký tự trong chuỗi
Để lấy được độ dài chuỗi : 
String message = "xin chao";
message.length();
Lấy được ký tự thứ i trong chuỗi :
s.charAt(index);// int index
String message = "Welcome to Java";
message.charAt(0); // result :'W'
*Cộng chuỗi :
Chúng ta có các phương pháp sau :
String s3 = s1.concat(s2);// dùng method concat()
String s3 = s1 + s2; // Dùng toán tử cộng
String myString = message + " and " + "HTML"; // cộng trực tiếp chuỗi.
* Lấy chuỗi con:
Để lấy một chuỗi con từ chuỗi mẹ , thì ta dùng method subString(...)
- public String substring(int beginIndex, int endIndex) : Return chuỗi từ ký tự thứ beginIndex tới ký tự endIndex của chuỗi mẹ
public String substring(int beginIndex) : Returm chuỗi con bắt đầu từ ký tự thứ beginIndex tới hết chuỗi của chuỗi mẹ.
Ví dụ :
String message = "Welcome to Java".substring(0, 11) + "HTML";
* Ký tự hoa , thường , Thay chuỗi:
Dùng 2 method toLowerCase and toUpperCase Để chuyển đổi 
Ví dụ :

S
"Welcome".toLowerCase() returns a new string, welcome.
"Welcome".toUpperCase() returns a new string, WELCOME.
"  Welcome".trim() returns a new string, Welcome.
"Welcome".replace('e' , 'A') returns a new string, WAlcomA.
"Welcome".replaceFirst("e" , "A") returns a new string, WAlcome.
"Welcome".replaceAll("e" , "A") returns a new string, WAlcomA.
II. Sử dụng StringBuffer & StringBuilder
Hai class này rất hữu dụng trong việc thay thế cũng như thao tác với chuỗi String.
StringBuilder
StringBuffer
Không có cơ chế đồng bộ
Có cơ chế đồng bộ
Không thể xử lý nhiều luồng một lúc
Có thể nhiều luồng truy nhập một lúc
Xử lý chuỗi nhanh hơn
Xử lý chuỗi chậm hơn
StringBuffer strBuf = new StringBuffer();
strBuf.append("Welcome");
strBuf.append(' ');
strBuf.append("to");
strBuf.append(' ');
strBuf.append("Java");
Hoặc insert vào một vị trí nào đó :
strBuf.insert(11, "HTML and ");
Hay thay đổi :
strBuf.delete(8, 11) changes the buffer to Welcome Java.
strBuf.deleteCharAt(8) changes the buffer to Welcome o Java.
strBuf.reverse() changes the buffer to avaJ ot emocleW.
strBuf.replace(11, 15, "HTML") changes the buffer to Welcome to HTML.
strBuf.setCharAt(0, 'w') sets the buffer to welcome to Java.
Ngoài ra StringBuffer còn cung cấp 1 method : reverse() . Đảo ngược chuỗi :
StringBuffer strBuf1 = strBuf.reverse();
* Nó có thể làm việc với các method :toString, capacity, length, setLength , charAt .. . giống như chuỗi String.
Tương tự như vậy với cách sử dụng StringBuilder.
Sau đây mình sẽ có một ví dụ so sánh tốc độ của StringBuilder , StringBuffer và String để các bạn dễ hình dung .
package nosoft.com;
import java.util.Date;
/**
 * 
 * @author nosoft
 *
 */
public class DemoString {
 public void demoStringBuffer(int i){
  long start = 0, end = 0;
  start = System.currentTimeMillis();
  System.out.println("start :" + start );
  while(i <100000){
   StringBuffer a = new StringBuffer("aaaa");
//   String b = "bbbbb";
   a.append("b");
   end = System.currentTimeMillis();
   i++;
  }
  System.out.println( "result : " + (end - start));
 }
 public void demoStringBuilder(int i){
  long start = 0, end = 0;
  start = System.currentTimeMillis();
  System.out.println("start :" + start );
  while(i <100000){
   StringBuilder a = new StringBuilder("aaaa");
//   String b = "bbbbb";
   a.append("b"); 
   end = System.currentTimeMillis();
   i++;
  }
  System.out.println( "result : " + (end - start));
 }
 public void demoString(int i){
  long start = 0, end = 0;
  start = System.currentTimeMillis();
  System.out.println("start :" + start );
  while(i <100000){
   String a = new String("aaaa");
//   String b = "bbbbb";
   a += "b"; 
   end = System.currentTimeMillis();
   i++;
  }
  System.out.println( "result : " + (end - start)); 
 }
 public static void main(String[] args) {
  DemoString demo = new DemoString();
  int i = 0;
  System.out.println("thoi gian String:" );
  demo.demoString(i);
  System.out.println("thoi gian StringBuilder:" );
  demo.demoStringBuilder(i);
  System.out.println("thoi gian StringBuffer:" );
  demo.demoStringBuffer(i);
 }
}
Kết quả như sau :
III. Cách sử dụng ArrayList và Vector
Mình sẽ giới thiệu trong loạt bài tiếp theo.

Tuesday, August 11, 2015

Share code - Java tutorial. part I

Hi all.
Dựa trên ý nghĩ tìm kiếm một bài code hoàn chỉnh của một chương trình là một công việc rất gian nan . Vì vậy mình chia sẻ các bạn code những gì mình tìm kiếm cũng như code được từ trước tới giờ . 
Có thể đi kèm theo những mô tả , và hình ảnh minh họa cho ứng dụng .
Bài viết này sẽ chia làm các part và được cập nhật liên tục .
Độ dài là max ping của trang thì sẽ được chuyển qua part khác.
Mọi đóng góp các bạn có thể đóng góp và comment bên dưới . Mình sẽ tiếp thu và làm cho bài cập nhật hoàn thiện hơn.
Thank all.

Sunday, August 9, 2015

Bài 10 - Kế thừa , Đa hình , Abstracts và Interface (Inheritance, Polymorphism, Abstracts & Interface)

Trong Java là một ngôn ngữ hướng đối tượng mạnh . Việc kế thừa là một công cụ rất mạnh mẽ và quan trọng trong việc phát triển của Java. Đặc điểm kế thừa này làm cho tính đa hình của Java được thể hiện rõ ràng và cụ thể hơn . Tăng tính tái sử dụng code khi viết chương trình.
I. Kế thừa (Inheritance)
1. Định nghĩa
Một class C1 extend từ một class C2 , thì nó sẽ kế thừa tất cả các đặc điểm về thuộc tính cũng như phương thức của class C2 . Và người ta gọi đó là sự kế thừa . Class C1 gọi là class con (subclass) , class C2 là class cha (supper class).
Một class con chỉ kế thừa từ một class cha , nhưng một class cha có thể được nhiều class con khác nhau kế thừa .
Cú pháp
public class GeometricObject {
// your code
}
public class Circle extends GeometricObject {
//your code
}
Trong UML design thì người ta thể hiện sử kế thừa như sau .
2. Cách sử dụng từ khóa supper
subclass muốn kế thừa các đặc tính của data fields và method của class cha thì phải có từ khóa supper để làm điều đó.
a. Gọi supperclass Contructors
Cú pháp
super(), or super(parameters);
Có từ khóa supper trong contructor của class con thì nó sẽ kế thừa contructors của cha nó.
Ví dụ :
public class SupperClass {
 int a;
 public SupperClass(int a) {
  this.a = a;
 }
 public SupperClass() {
  super();
 } 
}
public class SubClass extends SupperClass{
 public SubClass(int a) {
  super(a);
 }
}
b. Gọi tới Superclass Methods
Từ khóa supper còn được sử dụng để gọi tới method khác với contructors của lớp cha.
Cú pháp
super.method(parameters);
Ví dụ :
public void printCircle() {
  System.out.println("The circle is created " +
    super.getDateCreated() + " and the radius is " + radius);
}
3. Overriding Methods
Khi một subclass kế thừa một supper class mà có một method trùng tên với class cha của nó thì nó sẽ thực hiện ghi đè lên nội dùng của class cha nó.
Nhưng nó chỉ ghi đè được những method giống tham số ,mà không ghi đè được  method khác tham số
Ví dụ :
public class SupperClass {
 int a;
 public SupperClass(int a) {
  this.a = a;
 }
 public SupperClass() {
  super();
 }
 void tinhYeu(){
  System.out.println("Tinh yeu mau nang!");
 }
 void tinhYeu(int c , String b){
  System.out.println("tinh yeu la gi :" + a + " " + b);
 }
}
public class SubClass extends SupperClass{
 public SubClass(int a) {
  super(a);
  // TODO Auto-generated constructor stub
 }
 void tinhYeu(){
  System.out.println("han thu tram nam");
 }
 void tinhYeu(int b ){
  System.out.println("Tinh yeu va thu han " + b);
 }
 public static void main(String[] args) {
  SubClass sub = new SubClass(3);
  sub.tinhYeu();
  sub.tinhYeu(32);
 }
}
Sự khác nhau giữa override và overloading :
Như đã nói ở trên : override là phương thức xuất hiện ở lớp cha, lớp con cũng xuất hiện thì sẽ overload
Còn overload thì khi 2 method trong cùng 1 class cùng tên nhưng khác tham số , thì gọi tới method này thì sẽ overload tham số còn lại.
II . Abstract (Trừu tượng)
Lớp trừu tượng là một lớp cha , tuy nhiên điểm khác biệt là có từ khóa abstracts trước và nó chỉ cho lớp con kế thừa , không cho phép tạo instance hay không cho tạo thêm object trong đó.Và trong method abstract không có nội dung .
Biểu diễn của nó trong UML như sau .
Trong code nó có cú pháp như sau :
public abstract class GeometricObject {
 private String color = "white";
 private boolean filled;
 private java.util.Date dateCreated;
 /** Construct a default geometric object */
 protected GeometricObject() {
  dateCreated = new java.util.Date();
 }

 /** Return color */
 public String getColor() {
  return color;
 }
 /** Set a new color */
 public void setColor(String color) {
  this.color = color;
 }
 /**
  * Return filled. Since filled is boolean, so, the get method name is
  * isFilled
  */
 public boolean isFilled() {
  return filled;
 }
 /** Set a new filled */
 public void setFilled(boolean filled) {
  this.filled = filled;
 }
 /** Get dateCreated */
 public java.util.Date getDateCreated() {
  return dateCreated;
 }
 /** Return a string representation of this object */
 public String toString() {
  return "created on " + dateCreated + "\ncolor: " + color
    + " and filled: " + filled;
 }
 /** Abstract method getArea */
 public abstract double getArea();
 /** Abstract method getPerimeter */
 public abstract double getPerimeter();
}
LƯU Ý : Abstract class chỉ cho lớp khác kế thừa. Vì thế nên các method của nó không bao h được viết là private :)
III. Interface
Trong Java vì một class con không thể kế thừa từ nhiều class cha . Hay hiểu nôm na là mộtCon thì chỉ có 1 cha , nếu có hai cha thì cha kia không phải là cha (nghe rất hàn lâm :P)
Vì thế Java cung cấp một cái gọi là Interface , như một người bảo mẫu . Và một class con thì có thể implement nhiều bảo mẫu (interface) . Chúng có thêm một khái niệm về multi - Inheritance
Cách khai báo interface như sau :
modifier interface InterfaceName {
  /** Constant declarations */
  /** Method signatures */
}
Điểm đặc biệt là trong interface thì tất cả các method đều không có nội dung và phải khai báo bằng public và default . Không được dùng private và protected . Lưu ý nhé các bạn . Đây cũng là một câu hỏi có thể nhà tuyển dụng sẽ hỏi các bạn. Còn data field thì chỉ được khai báo hằng số . Không được phép khai báo biến . Tại sao vậy ? Câu trả lời là kiểu nó phải thế :D
public interface Comparable{
  public int compareTo(Object o)
}
Để class có thể kế thừa hay cài đặt interface người ta dùng từ khóa implements
Ví dụ :
public interface DemoInterfaces {
 final int a = 100;
 public int a();
 public void hienThi();
 void nhap();
}
public interface DemoInterface2 {
 public void hienThiNoiDung();
 public int tinhTong(int a , int b);
}
public class Result implements DemoInterfaces , DemoInterface2{
 @Override
 public void hienThiNoiDung() {
  // TODO Auto-generated method stub 
 }
 @Override
 public int tinhTong(int a, int b) {
  // TODO Auto-generated method stub
  return 0;
 }
 @Override
 public int a() {
  // TODO Auto-generated method stub
  return 0;
 }
 @Override
 public void hienThi() {
  // TODO Auto-generated method stub 
 }
 @Override
 public void nhap() {
  // TODO Auto-generated method stub
  
 }
}
Các bạn custom vào class con đã cài đặt interface là được . Như vậy chúng ta sẽ tiết kiệm được cách code đến cả hàng trăm dòng , nếu dùng điều này.
IV . Tính đa hình .
Các bạn trên mạng nói tính đa hình là nạp chồng của đối tượng này kia . Nhưng theo mình hiểu thì tính đa hình là sự thể hiện đa dạng của một đối tượng . Thành các đối tượng khác , giữ được các đặc điểm cũ đã tồn tại.
Nó rất dễ hiểu thôi , như cha các bạn sinh ra khoảng 8 người con chả hạn , người thì giống mũi , người thì giống mắt , người thì giống dáng đi vân vân . Thì mỗi thể hiện của người con , sẽ mang một số đặc điểm cố hữu của người cha . Nhưng có thêm các nét bổ sung mới . 
Trong lập trình Java cũng vậy , các đặc tính chung thì các bạn có thểm gộp vào 1 lớp cha . Các đặc tính riêng biệt của mỗi đối tượng khác nhau thì các bạn viết riêng , nhưng kế thừa lớp cha có các đặc tính chung đã tạo trước đó .
Như vậy gọi là đa hình.
Đơn giản đúng không nào :P
V. Một số method khác của đối tượng.
Dưới đây là một số method rất quan trọng vốn có của đối tượng :
- public boolean equals(Object object)
- public int hashCode()
- protected void finalize() throws Throwable
- protected native Object clone() throws CloneNotSupportedException
- public final native Class getClass()
a. equals method
Để kiểm tra 2 đối tượng có giống nhau không . Nếu giống trả về true , và ngược lại
Cú pháp :
object1.equals(object2);
The default implementation of the equals method in the Object class is:
public boolean equals(Object obj) {
  return (this == obj);
}
Ví dụ :
public boolean equals(Object o) {
  if (o instanceof Circle) {
  return radius == ((Circle)o).radius;
}
else
  return false;
}
b . hashCode method
hashCode là một phương thức trả về một số nguyên lưu trữ đối tượng trong bộ nhỡ băm đểlấy ra một cách nhanh chóng
cú pháp :
public int hashCode() {
  return (int)(radius * 1999711);
}
c . finalize method :
Khi một đối tượng không được xử dụng nữa thì được coi là rác , method này có chức năng là thu gom rác của chương trình . Nếu một lớp con ghi đè method này thì nó sẽ tự động thu gom rác nếu cần thiết
Cụ thể như sau :
public class FinalizationDemo {
   public static void main(String[] args) {
     Cake a1 = new Cake(1);
  Cake a2 = new Cake(2);
     Cake a3 = new Cake(3);
     // To dispose the objects a2 and a3
     a2 = a3 = null;
     System.gc(); // Invoke the Java garbage collector
   }
 }
 class Cake extends Object {
   private int id;
   public Cake(int id) {
     this.id = id;
     System.out.println("Cake object " + id + " is created");
   }
   protected void finalize() throws java.lang.Throwable {
     super.finalize();
     System.out.println("Cake object " + id + " is disposed");
    }
}
Result :
Cake object 1 is created
Cake object 2 is created
Cake object 3 is created
Cake object 2 is disposed
Cake object 3 is disposed
d. clone method.
Đôi khi bạn cần một bản sao của đối tượng . Cú pháp gán như sau :
newObject = someObject;
//Sẽ dẫn tới duplicate object
Chúng ta sử dụng như sau :
newObject = someObject.clone();
Ví dụ :
java.util.Date date = new java.util.Date();
java.util.Date date1 = (java.util.Date)(date.clone());
hoặc
int[] targetArray = (int[])sourceArray.clone();
e. getClass method
Một lớp được load để sử dụng .Nó tạo ra một đối tượng chứa thông tin của class như tên , contructors , method . Đối tượng này là instance của java.lang.Class . Chứa thông tin của calss.
Ví dụ :
Object obj = new Object();
Class metaObject = obj.getClass();
System.out.println("Object obj's class is " + metaObject.getName());
Result :
Object obj's class is java.lang.Object
OK , bài hướng dẫn hôm nay tạm dừng ở đây .
Tất nhiên chúng ta không quên bài tập vận dụng .
Nào cố lên đi các chiến binh .
Bài tập 1:
a. Xây dựng 1 lớp hình chữ nhật với các thuộc tính chiều dài , chiều rộng , viết các hàm tính chu vi và diện tích.
b. Xây dựng lớp hình vuông kế thừa lớp hình chữ nhật.
c. viết chương trình tính chu vi & diện tích hình vuông với độ dài nhập vào.
Code tham khảo : here
Bài tập 2:
Một trung tâm tin học cần quản lý giảng viên cố hữu và giảng viên thỉnh giảng.
Giảng viên cố hữu  ký hợp đồng lao động lớn hơn 1 năm  được hưởng lương hàng tháng  bao gồm lương thỏa thuận và lương cộng thêm theo quy định vượt giờ quy định trong tháng (số giờ quy định trong tháng là 40)
Giảng viên  tham gia giảng dạy thỉnh giảng ký hợp đồng lao động theo từng giờ học  được hưởng lương hàng tháng theo số giờ đứng lớp . Biết rằng mỗi giờ 200000d.
Thông tin giảng viên  cố hữu : tên giảng viên, email , địa chỉ , số giờ giảng dạy trong tháng , lương thỏa thuận, số giờ quy định chung.
Thông tin giảng viên thỉnh giảng : tên giảng viên , email,  địa chỉ , điện thoại ,  cơ quan làm việc , số giờ giảng dạy trong tháng.
Hãy xây dựng một chương trình cho phép nhân viên  trung tâm tin học  có thể thực hiện được các chức năng sau :
  1. Nhập thông tin giảng viên.
  2. xuất danh sách toàn bộ giảng viên .
  3. Xuất danh sách giảng viên thỉnh giảng
  4. Xuất danh sách giảng viên cố hữu.
  5. Tính tổng số tiền lương
  6. Tìm giảng viên có tổng lương cao nhất.
Sau đây là code tham khảo : here
pass extract : https://coderandtutorial.blogspot.com

Tuesday, July 14, 2015

Bài 9 - Lập trình hướng đối tượng (Object Oriented Programming)

Trong loạt bài trước mình đã hướng dẫn các bạn về các kỹ năng lập trình căn bản đối với ngôn ngữ Java . Tuy nhiênJava là ngôn ngữ lập trình hướng đối tượng rất mạnh mẽ . Và chúng ta sẽ dành nhiều thời gian hơn để nói về nó . Và đây cũng chiếm gần như chọn thời gian tìm hiểu của chúng ta.
I. Định nghĩa class của Object
1. Lập trình hướng đối tượng là gì :là ngôn ngữ mô tả các sự vật hiện tượng thông qua đối tượng.
Vậy đối tượng là gì : đối tượng là hiện tượng sự vật , được biểu hiện bằng các thuộc tính(data field) , và các hành động (behavior ) của nó được mô tả bằng các method hay event.
Trong Java người ta biểu diễn đối tượng thông qua class (template).
Ví dụ : class Nguoi có các field (name , age , salary...) và các behavior (nghe, nói , đọc ,viết ...)
Khi thiết kế hệ thống , chúng ta cần dùng các ngôn ngữ phân tích thiết kế khác . Ở đây tôi sẽ đề cập cho các bạn một dạng ngôn ngữ phân tích thiết kế thông thường hay sử dụng đó là UML(Unified Modeling Language) . Người ta dùng UML class diagram để thể hiện một class (hay template của đối tượng như sau)

Trong đó dữ liệu của thuộc tính được thể hiện ở dạng
dataFieldName: dataFieldType
Các contructor :
ClassName(parameterName: parameterType)
Các method :
methodName(parameterName: parameterType): returnType
Wao , chúng ta lại đề cập tới khái niệm contructor , vậy nó là gì.
Contructor được khai báo trùng với tên class , biểu diễn như một method nhưng lại không có kiểu dữ liệu trả về. Nó là một thể hiện của class .

Khi khai báo một class , thì nó sẽ tự động sinh ra một contructor rỗng (không có tham số).Mặc dù nó không thể hiện trên code.
Nếu một class viết một contructor có tham số (arguments) duy nhất cho class . Thì contructor này sẽ overload contructor default (không tham số) . Vì vậy nếu bạn gọi contructor(không tham số) nó sẽ báo lỗi .
Khi bạn muốn một thể hiện của class ở nhiều dạng , yêu cầu đầu vào cho class nhiều tham số thì bạn cũng có thể tạo rất nhiều contructor . Khi gọi tới contructor nào thì nó sẽ overload các contructor còn lại : Ví dụ:
public class DemoContructor {

       int a;
       String str ;
       float salary;
       public DemoContructor(){
              System.out.println("contructor rong");
       }
       public DemoContructor(int a){
              this.a = a;
              System.out.println("contructor co 1 tham so :" + a);
       }
      
       public DemoContructor(int a, String str, float salary) {
              super();
              this.a = a;
              this.str = str;
              this.salary = salary;
              System.out.println("contructor co 3 tham so:" + a + " " + str + " " + salary);
       }
       public static void main(String[] args) {
              // TODO Auto-generated method stub
              DemoContructor demo = new DemoContructor();
              DemoContructor demo2 = new DemoContructor(3);
              DemoContructor demo3 = new DemoContructor(4, "hello", 12);
       }

}
Đây cũng là một đặc tính đa hình trong Java .
Trong eclipse các bạn có thể tự generate các method contructor bằng các click vào Source trên thanh tabbar (Alt +S) hoặc chuột phải vào cửa sổ soạn thảo -->Source --> Generate Contructor using field
2. Biến static (static variables) , Constant (hằng số ) và method.
- Biến static và method static: Khi chúng ta muốn chia sẻ dữ liệu thì chúng ta dùng biến static . Biến static lưu trữ giá trị trong bộ nhớ dùng chung. Bởi vì vị trí ô nhớ dùng chung này , tất cả các đối tượng giống nhau trong class đều có thể thay đổi giá trị của biến static này. Java cũng support các method static để gọi tới các biến static. Ví dụ :
Các bạn chú ý : Chỉ có method static mới gọi được các biến static . Và chỉ có method static mới gọi được tới nhau.
Cách khai báo biến static và method static là :
static int numberOfObjects;

static int getNumberObjects() {
  return numberOfObjects;
}
- Hằng số và final method : Để chia sẻ dữ liệu cho toàn bộ project chúng ta dùng từ khóa final static để biểu diễn những giá trị không thể thay đổi . Hay đây chính là biểu diễn hằng số như trong toán học. (Những giá trị không bao giờ thay đổi ).Ví dụ
final static double PI = 3.14159265358979323846;
Tương tự như vậy final method cũng là một method không có bất kỳ method nào thay đổi giá trị của nó . Cũng không đươc kế thừa (cái này mình sẽ giới thiệu các bạn trong những bài học lần sau ).
public class DemoFinal {

       final static double PI = 3.14159265358979323846;
       final /*static*/ void show(){
              System.out.println("show :" + PI);
             
       }
       public static void main(String[] args) {
              DemoFinal fn = new DemoFinal();
              fn.show();
//            show();
       }
}
- Cách gọi tới method hoặc variable từ hàm main.
Thông thường chúng ta có 2 cách gọi method hay variable từ hàm main . Một là gọi trực tiếp , hai là gọi thông qua đối tượng.
* Cách 1 : gọi trực tiếp
Vì hàm main là một hàm static nên tất cả các variable và method của nó khi gọi tới phải là static
static int a = 23;
static void show(){
     System.out.println("ket qua show :" + a);
}
public static void main(String[] args) {
     show();
     System.out.println("ket qua show 2 :" + a);
}
*Cách 2 : gọi thông qua đối tượng. Ta dựa vào contructor như đã nói ở trên . Sau đó nhờ đối tượng để gọi tới.
public class DemoObject {

       String name = "Khai";
       int age = 24;
      
       public DemoObject() {
              super();
       }

       public DemoObject(String name, int age) {
              super();
              this.name = name;
              this.age = age;
       }

       void show(){
              System.out.println("name :" + name + "\nage" + age);
       }
       public static void main(String[] args) {
              DemoObject obj = new DemoObject();
              obj.show();
             
              DemoObject obj2 = new DemoObject("nosoft", 30);
              obj2.show();
       }
}
3. Khả năng truy nhập (Visibility Modifiers)
Java cung cấp các khả năng truy nhập dữ liệu như sau :
- public : Các biến dữ liệu hoặc method có thể sẽ được tất cả các lớp khác , hoặc method khác gọi tới ở bất kỳ nơi đâu trong project
- protected : Các biến dữ liệu hoặc method chỉ cho các lớp hoặc method khác gọi tới nếu cùng chung một package.
- private : Các biến dữ liệu hoặc method chỉ cho các method khác hoặc lớp nội hàm truy nhập nếu chung một class.
- default : truy nhập được trong class và trong package nhưng lại không truy nhập được từ class con
Đây cũng chính là tính bảo mật dữ liệu trong Java
Để tăng tính bảo mật project của bạn thì chúng ta nên dùng private cho các field . Và truy xuất dữ liệu thông quá các method getter và setter .
Thông qua các method getter và setter này để hạn chế khả năng truy nhập dữ liệu như thế nào tới từng loại user một. Tùy vào mục đích sử dụng.
public class Student {
  private int id;
  private BirthDate birthDate;

  public Student(int ssn, int year, int month, int day) {
    id = ssn;
    birthDate = new BirthDate(year, month, day);
    }

    public int getId() {
      if(id >1)
      return id;
      return 0;
    }

    public BirthDate getBirthDate() {
      return birthDate;
    }
}

public class BirthDate {
   private int year;
   private int month;
   private int day;

   public BirthDate(int newYear, int newMonth, int newDay) {
     year = newYear;
     month = newMonth;
     day = newDay;
   }

   public void setYear(int newYear) {
     year = newYear;
   }
}
public class Test {
  public static void main(String[] args) {
    Student student = new Student(111223333, 1970, 5, 3);
    BirthDate date = student.getBirthDate();
    date.setYear(2010); //Now the student birth year is changed!
  }
}
Muốn lấy dữ liệu của class Student thì ta dùng phương thức getter (getId , getBirthDate)
Muốn gán dữ liệu ta dùng phương thức setter (setYear)
Các bạn cũng có thể generate trong eclipse giống như generate contructor bằng phím tắt Alt+ S.
*Mở rộng : Cũng như với variable thì Array cũng là một object chứa các object khác là các phần tử .
Circle[] circleArray = new Circle[10];
for (int i = 0; i < circleArray.length; i++) {
  circleArray[i] = new Circle();
}
4. Lớp DateTime và Random
Trong Java hỗ trợ 2 thư viện rất hữu dụng đó là lớp Date và Random.
a . Date
Thuộc gói java.util.Date để thể hiện các toán tử current second , minute , hour . Có câu lệnh System.currentTimeMillis() để tính toán thời gian tại thời điểm hiện tại chính xác tới minisecond .
java.util.Date date =  new jave.util.Date();
System.out.println("The elapsed time since Jan 1, 1970 is " +
 date.getTime() + " milliseconds");
System.out.println(date.toString());
Result
The elapse time since Jan 1, 1970 is 1100547210284 milliseconds
Mon Nov 15 14:33:30 EST 2004
b. Random.
Thuộc gói java.util.Random generate ra các toán tử ngẫu nhiên . Trong phạm vi nào đó.
Ví dụ :
Random random1 = new Random(3);
System.out.print("From random1: ");
for (int i = 0; i < 10; i++)
  System.out.print(random1.nextInt(1000) + " ");
Random random2 = new Random(3);
System.out.print("\nFrom random2: ");
  for (int i = 0; i < 10; i++)
  System.out.print(random2.nextInt(1000) + " ");
Result
From random1: 734 660 210 581 128 202 549 564 459 961
From random2: 734 660 210 581 128 202 549 564 459 961
II. Tính đóng gói dữ liệu.
Hãy xem xét việc xây dựng một hệ thống máy tính, ví dụ. Máy tính cá nhân của bạn được tạo thành từ nhiều thành phần, chẳng hạn như một CPU, CD-ROM, ổ đĩa mềm, bo mạch chủ, quạt, và như vậy. Mỗi thành phần có thể được xem như là một đối tượng có các thuộc tính và phương thức. Để có được các thành phần để làm việc cùng nhau, tất cả chúng cần biết là mỗi thành phần được sử dụng và làm thế nào nó tương tác với những thành phần khác. Nó không cần phải biết làm thế nào nó hoạt động trong nội bộ. Việc thực hiện các thành phần với nhau phải được đóng gói và ẩn từ riêng chúng. Bạn có thể xây dựng một máy tính mà không biết làm thế nào thành phần được thực hiện như thế nào.
Vì vậy chúng ta có thể dùng các project này để làm library cho các project kia.
OK. Hôm nay hãn tạm dừng tại đây .
Mình sẽ không nêu ví dụ trong bài hướng dẫn này .
Nhưng vẫn có bài tập cho các bạn luyện tập về nó .
Bài 1: Tạo chương trình nhập và in ra thông tin một sinh viên (tên , tuổi , quê quán , học lực (điểm trung bình của ba môn : toán , văn , anh)) . Phải sử dụng contructor và getter setter để thực hiện.
Bài 2 : Tạo một chương trình nhập và in thông tin nhân viên (id , tên , tuổi , chức vụ , phòng ban (id phòng ban , loai phòng) , số lương) . Trong đó nếu chức vụ là trưởng phòng thì lương không được dưới 10 triệu. Nếu là giám đốc thì lương không dưới 20 tr
Source code : here
(Code khung)
pass extract : https://coderandtutorial.blogspot.com