Võ Văn Hải's blog

Chỉ có một điều tuyệt đối đó là mọi thứ đều tương đối…

Các bước căn bản tạo đối tượng trong java

Tôi xin giới thiệu với các bạn các bước căn bản để tạo 1 lớp trong java nhằn đặc tả 1 đối tượng nào đó.
Tuy nhiên, không phải lúc nào các bước này cũng đúng, nó chỉ đảm bảo trong các lớp đặc tả bình thường, còn các lớp đặc biệt thì bạn có thể “chế biến” nó 1 chút để phù hợp.
Trong bài viết này tôi có 1 ví dụ tạo 1 lớp đặc tả đối tượng Thí sinh dự thi Đại học.

Đầu tiên, bạn phải liệt kê các tính chất cần thiết của đối tượng (tùy ngữ cảnh), ví dụ cũng là nói về con người nhưng đối với đối tượng sinh viên bạn sẽ phải nghĩ đến những thuộc tính như mã số SV, lớp học, kết quả học tập,… còn với việc đặc tả cho 1 bệnh nhân bạn cần phải nghĩ đến những thuộc tính như tiền sử bệnh án,…
Với đối tượng thí sinh của chúng ta, giả sử ta cần quan tâm đến các tính chất: số báo danh, họ tên, điểm thi môn toán, điểm thi môn lý, điểm thi môn hóa.
Bước 1: Tạo 1 lớp biểu diễn cho đối tượng. tên lớp phải đảm bảo ngắn gọn, rõ ràng và dễ hiểu.
Ví dụ

public class Thisinh{
//nội dung của lớp sẽ đề cập tiếp theo
}

Bước 2: Ứng vỗi tính chất của đối tượng, ta khai báo thành 1 data instance trong lớp.
Theo tính chất Encapsulation của oop, ta khải khai báo các thuộc tính này có visibility modifier là private
Ví dụ


private String soBD;
private String hoTen;
private float diemToan;
private float diemLy;
private float diemHoa;

Bước 3: Ứng với mỗi data instance ở Bước 2, ta tạo các phương thức setters/getters.
Cũng theo tính chất Encapsulation, ta phải làm cho việc thay đổi giá trị của thuộc tính đảm đảo tính toàn vẹn dữ liệu.
Ví dụ:


public String getSoBD() {
return soBD;
}
public void setSoBD(String soBD) throws Exception{
if(soBD.trim().equals(""))
throw new Exception("Số báo danh không thể không có!");
this.soBD = soBD;
}
public String getHoTen() {
return hoTen;
}
public void setHoTen(String hoTen)throws Exception {
if(hoTen.trim().equals(""))
throw new Exception("Họ tên không thể không có!");
this.hoTen = hoTen;
}
public float getDiemToan() {
return diemToan;
}
public void setDiemToan(float diemToan) throws Exception{
if(diemToan10)
throw new Exception("Điểm không hợp lệ");
this.diemToan = diemToan;
}
public float getDiemLy() {
return diemLy;
}
public void setDiemLy(float diemLy) throws Exception{
if(diemLy10)
throw new Exception("Điểm không hợp lệ");
this.diemLy = diemLy;
}
public float getDiemHoa() {
return diemHoa;
}
public void setDiemHoa(float diemHoa) throws Exception{
if(diemHoa10)
throw new Exception("Điểm không hợp lệ");
this.diemHoa = diemHoa;
}

Lưu ý: đối với những thuộc tính mang tính chất chỉ đọc (read-only) ta không định nghĩa phương thức set cho nó. Còn với các phương thức chỉ ghi (write-only) ta không định nghĩa phuog7 thức get cho nó.
Bước 4: Nên tạo 2 hàm constructors cho đối tượng
constructor default: là constructor không có tham số, thường dùng để khởi gán các giá trị mặc định cho đối tượng.
constructor copy: constructor có đầy đủ tham số (số tham số của constructor này bằng với số data instance ta đã khai báo). Constructor này thường dùng để khởi tạo 1 đối tượng đầy đủ.
Ví dụ


public Thisinh() throws Exception{
this("","no-name",0f,0f,0f);
}
public Thisinh(String soBD, String hoTen, float diemToan, float diemLy,
float diemHoa)throws Exception {
setSoBD(soBD);
setHoTen(hoTen);
setDiemToan(diemToan);
setDiemLy(diemLy);
setDiemHoa(diemHoa);
}

Bước 5: Định nghĩa thuộc tính nhận diện (khóa)cho đối tượng bằng cách viết lại (overrid) 2 phương thức equals hashCode
Các phương thức này rất quan trọng trong việc lập trình sau này, dùng để phân biệt 2 đối tượng.
Trong ví dụ của chúng ta, 2 thí sinh phân biệt với nhau nhờ và thuộc tính số báo danh.


@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((soBD == null) ? 0 : soBD.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Thisinh other = (Thisinh) obj;
if (soBD == null) {
if (other.soBD != null)
return false;
} else if (!soBD.equals(other.soBD))
return false;
return true;
}

Bước 6: Định nghĩa phương thức đặc tả dạng chuỗi của đối tượng (phương thức toString)
Đây là phương thức sẽ được tự động triệu gọi khi chúng ta làm việc với việc kết xuất đối tượng ra màn hình hay lên 1 GUI controls nào đó. Ở đây đơn giả tôi xuất ra họ tên của 1 sinh viên, còn bạn có thể xuất ra bất cứ thứ gì bạn muốn.:-)


@Override
public String toString() {
return hoTen;
}

Bước 7: Viết các business methods của đối tượng.
Đây là bước quan trọng nhất bởi nó định nghĩa tập các dịch vụ của đối tượng cung cấp cho bên ngoài.


/**
* Kiểm tra 1 thí sinh có đậu hay không
* @return true nếu sinh viên có tổng số điểm trên 15 và không
* có điểm nào dưới 3.
*/
public boolean CheckPassed() {
return TongDiem()>15 && diemToan>=3&&diemHoa>=3 && diemLy>=3;
}
/**
* Tổng điểm của thí sinh
* @return: tổng điểm
*/
public float TongDiem() {
return diemHoa+diemLy+diemToan;
}

**Ở đây chúng ta lưu ý về cách ghi chú.


Như vậy chúng ta đã có thể có 1 lớp đặc tả tốt đồi đấy. Chúc các bạn thành công. Sau đây là toàn bộ code của chương trình

package descript;

public class Thisinh {

//Các instatance data

private String soBD;

private String hoTen;

private float diemToan;

private float diemLy;

private float diemHoa;

//=======================================================================

//các phương thức setters/getters

public String getSoBD() {

return soBD;

}

public void setSoBD(String soBD) throws Exception{

if(soBD.trim().equals(“”))

throw new Exception(“Số báo danh không thể không có!”);

this.soBD = soBD;

}

public String getHoTen() {

return hoTen;

}

public void setHoTen(String hoTen)throws Exception {

if(hoTen.trim().equals(“”))

throw new Exception(“Họ tên không thể không có!”);

this.hoTen = hoTen;

}

public float getDiemToan() {

return diemToan;

}

public void setDiemToan(float diemToan) throws Exception{

if(diemToan<0||diemToan>10)

throw new Exception(“Điểm không hợp lệ”);

this.diemToan = diemToan;

}

public float getDiemLy() {

return diemLy;

}

public void setDiemLy(float diemLy) throws Exception{

if(diemLy<0||diemLy>10)

throw new Exception(“Điểm không hợp lệ”);

this.diemLy = diemLy;

}

public float getDiemHoa() {

return diemHoa;

}

public void setDiemHoa(float diemHoa) throws Exception{

if(diemHoa<0||diemHoa>10)

throw new Exception(“Điểm không hợp lệ”);

this.diemHoa = diemHoa;

}

//=======================================================================

//constructors

public Thisinh() throws Exception{

this(“”,“no-name”,0f,0f,0f);

}

public Thisinh(String soBD, String hoTen, float diemToan, float diemLy,

float diemHoa)throws Exception {

setSoBD(soBD);

setHoTen(hoTen);

setDiemToan(diemToan);

setDiemLy(diemLy);

setDiemHoa(diemHoa);

}

//=======================================================================

@Override

public int hashCode() {

final int prime = 31;

int result = 1;

result = prime * result + ((soBD == null) ? 0 : soBD.hashCode());

return result;

}

@Override

public boolean equals(Object obj) {

if (this == obj)

return true;

if (obj == null)

return false;

if (getClass() != obj.getClass())

return false;

Thisinh other = (Thisinh) obj;

if (soBD == null) {

if (other.soBD != null)

return false;

} else if (!soBD.equals(other.soBD))

return false;

return true;

}

//=======================================================================

@Override

public String toString() {

return hoTen;

}

//=======================================================================

//Business methods

/**

* Kiểm tra 1 thí sinh đậu hay không

* @return true nếu sinh viên tổng số điểm trên 15 không

* điểm nào dưới 3.

*/

public boolean CheckPassed() {

return TongDiem()>15 && diemToan>=3&&diemHoa>=3 && diemLy>=3;

}

/**

* Tổng điểm của thí sinh

* @return: tổng điểm

*/

public float TongDiem() {

return diemHoa+diemLy+diemToan;

}

}

28 Responses to “Các bước căn bản tạo đối tượng trong java”

  1. Ngan said

    Thua thay cho em hoi la tu khoa “emplements” khac “extends” khac nhau nhu the nao. Chung dung de lam gi? Co phai ca 2 tu khoa do deu co tinh thua ke khong? Tu khoa “extends” dung de thua ke tu 1 class, con “emplement” dung de thua ke tu “interface” phai khong a? Ma “interface” duoc hieu la 1 giao dien, vay emplement “interface” la tao class giong interface do ha thay?
    Em cam on thay !!! Mong hoi am cua thay trong thoi gian nhanh nhat.

  2. hiếu nguyễn said

    hay hay đấy.

  3. Cong Hoat said

    Thua thay cho em hoi lam the nao de ghi mot doi tuong vao file va xuat 1 doi tuong ra man hinh? Em cam on.

  4. danhhieu said

    tương đối dài.cái cách này giảng bài thì tốt chứ để code chương trình thì ko dùng dc.

  5. Ho Hoang Anh said

    Em ko hiểu lắm 2 phương thức equals và hashCode dung để làm gì ? cụ thể đoạn code
    @Override
    public int hashCode() {
    final int prime = 31; //tại sao lại khởi tạo prime=31 để làm gì
    int result = 1; // biến này có giá trị 1 để làm gì
    result = prime * result + ((soBD == null) ? 0 : soBD.hashCode()); //điều kiện này để làm gì
    return result;
    }
    // và cả những dòng code dưới này nữa
    @Override
    public boolean equals(Object obj) {
    if (this == obj)
    return true;
    if (obj == null)
    return false;
    if (getClass() != obj.getClass())
    return false;
    Thisinh other = (Thisinh) obj;
    if (soBD == null) {
    if (other.soBD != null)
    return false;
    } else if (!soBD.equals(other.soBD))
    return false;
    return true;
    }

    Mong được sự giúp đỡ giải đáp của tất cả các bạn và thầy, em cám ơn !

  6. Jun said

    Thầy giải thích rõ hơn vể hàm hashCode(), và hàm equal(), công dụng cua các contructor, khi nào cần dùng contructor? Em không hiểu lắm.
    Thanks Thầy!

  7. Thanh Thảo said

    Mong thầy trả lời những thắc mắc đó cho em với

  8. hieu nghia said

    minh dang lam chuong trinh quan ly nhan su ai co de tai ve quan ly cho minh xin di
    bao gom dac ta va chuong trinh luon nhe

  9. Duy said

    public Thisinh(String soBD, String hoTen, float diemToan, float diemLy,float diemHoa)
    {
    try{
    setSoBD(soBD);
    setHoTen(hoTen);
    setDiemToan(diemToan);
    setDiemLy(diemLy);
    setDiemHoa(diemHoa);
    }
    catch(Exception ex)
    {
    System.out.println (ex.getMessage());
    }

    Mình viết lại phương thức thức kiểu nay không biết có sao không nhỉ???

  10. Võ Văn Hải said

    Đúng là như thế!

  11. Nguyễn Phúc Thái said

    em cũng như bạn Hồ Hoàng Anh muốn hỏi thầy về đoạn code trên ,em không hiểu nó làm gì cả …
    Thanks Thầy !

  12. Võ Văn Hải said

    Ví như bạn tạo 1 bảng trong cơ sở dữ liệu. bạn phải tạo trường khóa. Phương thức equals là cách thức tạo “khóa” cho đối tượng. Phương thức hashCode tạo ra 1 mã băm dùng trong việc xác định đối tượng trong 1 tập hợp.

  13. Võ Văn Hải said

    to Duy:
    bạn phải viết như sau mới ok:

    public Thisinh(String soBD, String hoTen, float diemToan, float diemLy,float diemHoa)throws Exception
    {
    setSoBD(soBD);
    setHoTen(hoTen);
    setDiemToan(diemToan);
    setDiemLy(diemLy);
    setDiemHoa(diemHoa);
    }
    
  14. Thưa Thầy…Em làm giống như những gì Thầy chỉ ở trên và em có thêm 1 số hàm như sau :

    public void NhapThiSinh(){
    Scanner nhap = new Scanner(System.in);

    System.out.print(“Nhap vao So Bao Danh cua thi sinh : “);
    this.SoBD = nhap.nextLine();

    System.out.print(“Nhap vao ho ten cua thi sinh : “);
    this.HoTen = nhap.nextLine();

    System.out.print(“Nhap diem mon Toan : “);
    this.DToan = Integer.parseInt(nhap.nextLine());

    System.out.print(“Nhap vao diem mon Ly : “);
    this.DLy = Integer.parseInt(nhap.nextLine());

    System.out.print(“Nhap diem mon Hoa : “);
    this.DHoa = Integer.parseInt(nhap.nextLine());

    }

    public void XuatThiSinh(){
    System.out.printf(“So Bao Danh : “, this.SoBD);
    System.out.printf(“Ho Va Ten : “, this.HoTen);
    System.out.printf(“Diem Toan : “, this.DToan);
    System.out.printf(“Diem Ly : “, this.DLy);
    System.out.printf(“Diem Hoa : “, this.DHoa);
    }

    public boolean KiemTraDau(){
    return TongDiem()>15&&DToan>=3&&DLy>=3&&DHoa>=3;
    }

    public float TongDiem(){
    return DToan+DLy+DHoa;
    }

    public static void main(String[] args) {
    // TODO code application logic here
    NhapThiSinh();
    XuatThiSinh();
    KiemTraDau();
    }

    Mà sao nó chạy…Thầy giúp em với. Em cám ơn Thầy nhiều !!!

  15. Võ Văn Hải said

    Thisinh ts=new Thisinh();
    ts.NhapThisinh();
    ts.XuatThisinh();
    
  16. Nguyễn Văn Đức said

    Thưa thầy, Thầy có thể giải thích cụ thể hơn cho em về hashcode và equals đc ko ạ. Giải thích từng dòng trong 2 cái đó đc ko. Em chưa hiểu lắm về phần ấy ạ

  17. Võ Văn Hải said

    @Override
    public boolean equals(Object obj) {
    if (this == obj) return true;
    if (obj == null) return false;
    if (getClass() != obj.getClass()) return false;
    Thisinh other = (Thisinh) obj;
    if (soBD == null) {
    if (other.soBD != null)
    return false;
    } else if (!soBD.equals(other.soBD))
    return false;
    return true;
    }
    

    dòng 1 nếu so sánh nó là chính nó thì luôn là true.
    dòng 2: nếu obj là null thì luôn là false (không có gì để so sánh)
    dòng 3: nếu so sánh 2 loại đối tượng khác nhau -> false
    các dòng còn lại chắc bạn hiểu

  18. Nguyễn Văn Đức said

    Em cảm ơn thầy hải. Đó là những gì em muốn hỏi. :))

  19. Nguyễn Văn Đức said

    em làm 1 bài quản lí sách có sử dụng hashCode() và equals() y đúc thầy ở class book rồi ạ.
    Đây là phần nhập sách trong class listbook của em

    Nhưng sao em sử dụng list.contains(h) ở vị trí dưới lại sai thầy nhỉ. Khi chạy thì nó luôn đúng(list.contains(h) luôn bằng true) cho dù nhập trùng mã sách.

    public void addListBook() {
    Scanner input = new Scanner(System.in);
    System.out.print(“Nhap tong so sach can them vao: “);
    int ts = input.nextInt();
    for(int i = 0; i < ts; i++) {
    System.out.print("Sach thu " + (i+1)+ ": ");
    book h = new book();
    h.addBook(); // phương thức addBook ở trong class book. (gồm nhập các đối tượng như mã sách, tên sách,…)
    list.add(h);
    if(list.contains(h)) {
    System.out.print("Ma sach trung nhau. Nhap lai ma sach " + (i+1));
    list.get(i).setms(input.nextLine());
    }
    ghiFile(h);
    }
    }

  20. Võ Văn Hải said

    Trong class listbook, em tạo phương thức thêm sách như sau:

    //với list là 1 ArrayList<Book>
    public boolean addBook(Book b){
    	if(list.contains(b))
    		return false;
    	return list.add(b);
    }
    

    việc nhập liệu bạn nên làm ở hàm main.

  21. Nguyễn Văn Đức said

    Thưa thầy, vì sao mình lại phải thêm 1 phương thức public boolean addBook(book b) ạ. Bản thân list.contains(b) là boolean rồi mà thầy.

  22. Võ Văn Hải said

    phương thức contains kiểm tra xem có 1 obj trong collection chưa thôi,thêm vào col thì phải add chứ.

  23. Truong Quang Thang said

    Cảm ơn thầy bài đọc rất hay!
    Chổ override hàm equals của bài này em làm thế này được không thầy?
    @Override
    public boolean equals(Object obj) {
    if(obj instanceof ThiSinh)
    {
    if(this.soBD.compareTo(((ThiSinh)obj).SoBD)==0)
    return true;
    else
    return false;
    }
    return false;
    }
    Thêm một vấn đề nữa là bên hàm main em nên Caught Exception bên contructor ném qua như thế nào là tối ưu ạ?

  24. Cao Hữu Tú said

    Cám ơn Thầy! bài viết rất hay.

  25. sua chua said

    Cám ơn bạn nhiều lắm về bài viết chi tiết

  26. Trần Anh Tân said

    Thầy ơi ! Cho em hỏi trong java có cách nào để mình kiểm tra đối tượng nó thuộc lớp nào không vậy thầy.
    Ví dụ như mình có hai lớp Thư Kí và Văn Phòng kế thừa từ lớp Nhân Viên. Khi mình tạo một đối tượng Nhân Viên nhưng new thành Thư Kí hoặc Văn Phòng. Vậy có cách nào kiểm tra là nó đang thuộc lớp nào hay không khi mình chưa biết.
    Cám ơn thầy !

  27. Võ Văn Hải said

    có nhiều cách. Em có thể dùng toán tử instanceof để kiểm tra chẳng hạn.

  28. Hòang RX said

    Bài viết thì hay mà chữ bé quá, em phải căng mắt ra đọc

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

 
%d bloggers like this: