Chương 8
Lớp và Đối tượng
Chương 8: Lớp và Đối tượng
o Đối tượng và lớp. o Thuộc tính và phương thức của lớp o Hàm tạo o Từ bổ nghĩa (public, private, protected). o Từ khóa this. o Tính đóng gói o Tính đa hình o Tính kế thừa o Lớp trừu tượng
Đối tượng và lớp
o Một đối tượng biểu diễn một thực thể cụ thể, riêng
biệt trong thế giới thực
o Lớp là mô tả trừu tượng cho một đối tượng cụ thể. o Đối tượng được xây dựng từ lớp nên được gọi là thể
hiện của lớp (class instance).
Đối tượng và lớp
o Lớp chứa:
Tên class Các thuộc tính (properties) mô tả các trạng thái
(state) của đối tượng.
Các phương thức khởi tạo (constructor) Các phương thức (methods) mô tả các hành vi
(behavior) của đối tượng
Khai báo lớp (class)
//khai báo các thuộc tính của lớp
//các hàm tạo constructor1 constructor2
class
//các phương thức
}
Khai báo lớp (class)
o class: là từ khóa của java o ClassName: là tên đặt cho lớp o field_1, field_2: các thuộc tính (các biến, hay các
thành phần dữ liệu của lớp)
o constructor: là phương thức xây dựng, khởi tạo đối
tượng của lớp.
o method_1, method_2: là các phương thức thể hiện các thao tác xử lý, tác động lên các thuộc tính của lớp.
Ví dụ khai báo lớp
Thuộc tính
String ten; int tuoi; double hsl;
Hàm khởi tạo
ConNguoi(){ } ConNguoi(String t1, int t2){ ten = t1; tuoi = t2; }
Phương thức
public void tangLuong(double d1){ hsl = d1; }
class ConNguoi{ }
Thuộc tính của lớp
o Vùng dữ liệu (fields) hay thuộc tính (properties) của
lớp được khai báo bên trong lớp như sau:
// …
class
Thuộc tính của lớp
o
o
Từ bổ nghĩa chỉ phạm vi truy xuất
Mặc định (không có từ bổ nghĩa): các lớp, biến (dữ liệu) có thể được truy nhập bởi bất kỳ lớp nào trong cùng gói (package)
public: Lớp, dữ liệu, phương thức có thể được truy nhập bởi tất cả các lớp trong bất kỳ gói nào
protected: Dữ liệu hoặc phương thức có thể được truy nhập bởi các lớp con trong bất kỳ gói nào hoặc các lớp trong cùng gói
private: Dữ liệu hoặc phương thức chỉ được truy nhập bởi lớp đã khai báo nó
Từ bổ nghĩa chỉ phạm vi truy xuất
public + mặc định dùng khai báo cho cả lớp + các thành phần của lớp (thuộc tính và phương thức)
protected + private chỉ dùng khai báo cho các thành phần của lớp, không dùng cho khai báo lớp
Người ta thường tạo thêm các phương thức để thiết lập/lấy giá trị của các biến private (getter và setter).
Nguyên tắc chung: Dùng private cho thuộc tính và public cho phương thức
Ví dụ thuộc tính của lớp
Thuộc tính của lớp
(XeMay và Xe2Banh cùng chung 1 gói XeDongCo) - Thuộc tính private không được phép truy cập từ bên ngoài lớp. - Mặc định, public, protected OK
Thuộc tính của lớp
(Xe2Banh và XeBo không cùng 1 gói) - Thuộc tính mặc định, private, protected không được phép truy cập từ gói bên ngoài. - public OK (được quyền truy cập trong bất kỳ gói nào)
Thuộc tính của lớp
(HonDa và Xe2Banh trong cùng gói) - Thuộc tính private của lớp cha không được phép truy cập từ lớp con kế thừa. - Mặc định, public, protected OK
Thuộc tính của lớp
(XeDap và Xe2Banh không cùng chung gói) - Thuộc tính mặc định, private của lớp cha không được phép truy cập từ lớp con kế thừa nằm bên ngoài gói. - public, protected OK
Phương thức setter và getter
o Nguyên tắc chung: Dùng private cho thuộc tính và public cho phương thức. truy cập các thuộc tính khi nó là private?
Phương thức setter và getter
o Phương thức setter: gán giá trị cho các thuộc tính của
đối tượng.
o Phương thức setter: trả về các thuộc tính của đối
tượng.
o Click phải chuột -> chọn Source ->chọn Geneate
Getters and Setters -> chọn các thuộc tính.
o Ví dụ: - Lớp sinh viên có 2 thuộc tính + Họ tên + Tuổi Yêu cầu: xây dựng phương thức setter và getter cho các thuộc tính trên.
Phương thức setter và getter
Phương thức của lớp
Khai báo phương thức:
return 1.5 * chiphisx;
public class XeMay{ public String nhasx; public float tinhGiaBan() { } }
o Hàm hay phương thức (method) trong Java là khối lệnh thực hiện các chức năng, các hành vi xử lý của lớp lên vùng dữ liệu.
Phương thức của lớp
o
tượng khác đối với các phương thức của lớp người ta thường dùng các tiền tố sau:
public, protected, private, static, final, abstract, synchronized
o
một lớp.
o
Phương thức của lớp
o public, protected, private. o static:
Phương thức lớp dùng chung cho tất cả các thể hiện của lớp. Có thể được thực hiện kể cả khi không có đối tượng của lớp
chứa phương thức đó.
o final: phương thức có tiền tố này không được khai báo chồng
ớ các lớp dẫn xuất.
o abstract:
Phương thức không cần cài đặt (không có source code). Sẽ được hiện thực (cài đặt) trong các lớp dẫn xuất từ lớp
này.
o synchoronized: dùng để ngăn các tác động của các đối tượng khác lên đối tượng đang xét trong khi đang đồng bộ hóa. Dùng trong lập trình multithreads.
Khai báo - khởi tạo đối tượng (thể hiện)
SV1.
• VD: ConNguoi SV1 = new ConNguoi(); • VD: ConNguoi GV1 = new ConNguoi();
Phân biệt kiểu cơ sở và kiểu đối tượng
ConNguoi SV1 = new ConNguoi();
o Kiểu cơ sở: int i = 1; o Kiểu đối tượng: o Sau khi tạo: SV1
SV1: ConNguoi
HoTen = “” ………
Phân biệt kiểu cơ sở và kiểu đối tượng
Truy xuất đối tượng
o Tham chiếu dữ liệu của đối tượng: bienDoiTuong.duLieu o Gọi phương thức của đối tượng: bienDoiTuong.tenPhuongthuc
Hàm xây dựng/ Hàm tạo (Constructor)
o Là một loại phương thức đặc biệt của lớp. o Dùng gọi tự động khi khởi tạo một thể hiện của lớp. o Có thể dùng để khởi gán những giá trị măc định. o Không có giá trị trả về. o Có thể có tham số hoặc không có tham số. o Phải có cùng tên với lớp và được gọi đến khi dùng từ
khóa new
Hàm xây dựng/ Hàm tạo (Constructor)
o Lưu ý: thông thường để an toàn, dễ kiểm soát và làm chủ mã nguồn chương trình chúng ta nên khai báo một constructor cho lớp.
o Nếu một lớp không có constructor thì
Java sẽ cung cấp cho lớp một constructor mặc định
(default constructor).
Những thuộc tính, biến của lớp sẽ được khởi tạo bởi các giá trị mặc định (số: thường là giá trị 0, kiểu luận lý là giá trị false, kiểu đối tượng giá trị null, …)
Hàm xây dựng/ Hàm tạo (Constructor)
o Hàm tạo có đối số
ConNguoi(String t) { HoTen = t; }
HoTen = “Nguyễn Văn A”;
o Hàm tạo không có đối số ConNguoi(){ }
o Tạo đối tượng sử dụng hàm tạo
ConNguoi SV1 = new ConNguoi(“Nguyen Van A);
Hàm xây dựng/ Hàm tạo (Constructor)
o p1: có HoTen = “Lan”, CMND = 351xxxxxx o p2: có HoTen = “”, CMND = “”
public class ConNguoi { public CoNguoi() { } public ConNguoi(String s_HoTen, String s_CMND){ HoTen = s_HoTen; CMND = s_CMND; } public static void main( String args[ ] ){ ConNguoi p1= new ConNguoi(“Lan”, “351xxxxxx”); ConNguoi p2= new ConNguoi(); }
Chồng phương thức
o Việc khai báo trong một lớp nhiều phương thức có
// khai báo fields … public float tinhGiaBan(){ return 2 * chiphisx; } public float tinhGiaBan(float huehong){ return (2 * chiphisx + huehong); }
public class XeMay{ }
31
cùng tên nhưng khác tham số (khác kiểu dữ liệu, khác số lượng tham số) gọi là khai báo chồng phương thức (overloading method).
Các biến, hằng, phương thức tĩnh
o Từ bổ nghĩa static được dùng để khai báo các biến, hằng
và phương thức sử dụng chung trong lớp.
public final static double PI=3.1416;
o Hằng static: o Biến static:
Chỉ phụ thuộc vào lớp mà không phụ thuộc vào đối
tượng.
Biến static có thể truy cập trực tiếp bằng tên class mà
không cần bất kỳ đối tượng nào.
Cú pháp: Tên_class.Tên_biến _static
Biến không static: Tên_đối_tượng.Tên_biến Biến static chỉ khởi tạo một lần khi chương trình bắt
đầu thực thi
Các biến, hằng, phương thức tĩnh
count++; a++;
BienTinh b1 = new BienTinh(); System.out.println("count lần 1 = "+BienTinh.count); System.out.println("b1.a = "+b1.a); BienTinh b2 = new BienTinh(); System.out.println("count lần 2= "+BienTinh.count); System.out.println("b2.a = "+b2.a);
public class BienTinh{ public static int count = 0; public int a = 0; public BienTinh() { } public static void main(String[] args) { } }//biến count dùng chung cho tất cả các đối tượng (b1 và b2).
Các biến, hằng, phương thức tĩnh
count++; a++;
BienTinh b1 = new BienTinh(); System.out.println("count lần 1 = "+BienTinh.count); System.out.println("b1.a = "+b1.a); BienTinh b2 = new BienTinh(); System.out.println("count lần 2= "+BienTinh.count); System.out.println("b2.a = "+b2.a);
public class BienTinh{ public static int count = 0; public int a = 0; public BienTinh() { } public static void main(String[] args) { } }//biến count dùng chung cho tất cả các đối tượng (b1 và b2).
Các biến, hằng, phương thức tĩnh
o Phương thức static:
Chỉ phụ thuộc và lớp mà không phụ thuộc vào đối
tượng.
Phương thức static có thể truy cập trực tiếp bằng tên
class mà không cần bất kỳ đối tượng nào.
Cú pháp : Tên_lớp.Tên_phương_thức_static Phương thức static chỉ có thể truy cập vào các thành phần static mà không thể truy cập vào các thành phần không static.
public static int getNum(){ return num; }
Từ khóa this
o Thay thế cho đối tượng hiện tại.
o Gọi các
constructor khác của đối tượng.
this.DiemTB = so; this.HoTen = ten;
}
this.tinhDiemTB()
public class SinhVien{ float DiemTB; String HoTen; // Contructor của lớp A public SinhVien(float so, String ten){ } float tinhDiemTB() { // … void hienThi(){ }
}
Mảng đối tượng
ConNguoi[] SV = new ConNguoi[10];
o Khai báo: o Khởi tạo: for(int i=0; I < SV.length; i++){ SV[i] = new ConNguoi(); }
Mảng đối tượng
Ví dụ
o Xây dựng lớp NhanVien theo các yêu cầu sau:
Các thuộc tính: họ tên, HSL, LCB và số nhân viên.
Trong đó LCB và số nhân viên là biến kiểu static, LCB được khởi tạo mặc nhiên là 540000, số nhân viên được khởi tạo giá trị là = 0.
Các hàm tạo: NhanVien() và NhanVien(hoTen,HSL). Mỗi khi có một đối tượng được tạo thì thuộc tính số nhân viên tăng lên 1.
Các phương thức: tangHSL(HSL mới): Tăng hệ số
lương của một nhân viên, tangLCB(LCB mới): Tăng lương cơ bản, tinhLuong(): Tính lương NV theo công thức: Lương = HSL*LCB và inNV(): In thông tin về nhân viên và lương của nhân viên
Ví dụ
Đặc điểm OOP trong Java
o Để hỗ trợ những nguyên tắc cơ bản của lập trình hướng đối tượng (OOP), tất cả các ngôn ngữ lập trình OOP, kể cả Java đều có ba đặc điểm chung: Tính đóng gói (Encapsulation) Tính đa hình (Polymorphimsm) Tính kế thừa (Inheritance)
Tính đóng gói
o Giúp cho các đối tượng giấu đi một phần các chi tiết cài đặt và chỉ công bố ra ngoài những gì cần công bố để trao đổi với các đối tượng khác.
o Đối tượng là một thành tố hỗ trợ tính đóng gói. o Đơn vị đóng gói cơ bản của ngôn ngữ java là class. Java dùng class để xây dựng những đối tượng. Những đối tượng là những thể hiện (instances) của một class.
Tính đa hình
void method_1( ){ System.out.println(“Day la con vat”);}
void method_1( ) {System.out.println(“Day la con meo”);}
arr_DV[0] = meo1;
for (int i=0; i<2; i++) { dv2 = arr_DV[i]; dv2.method_1();
class DongVat{ } class ConMeo extends DongVat { } class C { public static void main(String[] args) { // Tạo một mảng 2 phần tử kiểu A DongVat arr_DV = new DongVat[2]; ConMeo meo1 = new ConMeo(); DongVat dv2; } } }
Tính đa hình
o Vòng lặp for trong đoạn chương trình trên:
Với i = 0 thì biến dv2 có kiểu là ConMeo, và lệnh dv2.method_1() sẽ gọi thực hiện phương thức method_1 của lớp ConMeo.
Với i = 1 thì biến dv2 có kiểu là DongVat, và lệnh dv2.method_1() sẽ gọi thực hiện phương thức method_1 của lớp DongVat.
o Đối tượng dv2 có thể nhận kiểu DongVat hay ConMeo. o Hay nói các khác, một biến đối tượng thuộc lớp cha có thể tham chiếu đến bất kỳ đối tượng nào của bất kỳ lớp con nào của lớp cha
o Ngược lại một biến của lớp con không thể tham chiếu
đến bất kỳ đối tượng nào của lớp cha.
Tính đa hình
o Cha tham chiếu đến đối tượng con (tính đa hình) o Ngược lại thì không. o Con kế thừa thuộc tính, phương thức của cha
(tính kế thừa)
Tính kế thừa
o Một lớp con (subclass) có thể kế thừa tất cả những vùng dữ liệu và phương thức của một lớp khác (siêu lớp - superclass).
o Khi đó chúng ta gọi lớp mới là lớp dẫn xuất (derived
class) từ lớp cũ (superclass).
o Một lớp siêu lớp trực tiếp (immediate supperclass): Lớp C kế thừa từ B mà lớp B được kế thừa từ A. vậy lớp A là một siêu lớp trực tiếp của C.
o Dùng từ khóa extends để chỉ lớp dẫn xuất.
class A extends B{ // nội dung lớp }
Tính kế thừa
• Thực tế, lớp con thường được mở rộng để chứa nhiều thông tin chi tiết và nhiều chức năng hơn so với lớp cha của nó.
Tính kế thừa
• Truy xuất superclass từ subclass: Dùng từ khóa super
– Từ khóa super được dùng để thay cho superclass,
tương tự như this thay cho đối tượng được gọi.
– super được dùng để: gọi 1 hàm tạo (contructor) hoặc
một phương thức của superclass
Gọi hàm khởi tạo của Superclass
Khai báo tường minh
Khai báo không tường minh
• Cách gọi: super() hoặc super(tham_số) • Lưu ý: Lệnh trên phải được đặt tại dòng đầu tiên trong hàm tạo của lớp con và là cách duy nhất để gọi 1 hàm tạo của lớp cha.
Gọi phương thức của Superclass
double findVolume() { return super.findArea() * length; } • Cách gọi: super.method(tham_số) • Ví dụ:
Khai báo chồng phương thức
o Tính kế thừa giúp cho các lớp con nhận được các
thuộc tính/phương thức public và protected của lớp cha.
o Đồng thời cũng có thể thay thế các phương thức của
lớp cha bằng cách khai báo chồng.
Khai báo chồng phương thức
public class XeGa extends XeMay{
this.nhasx = s_nhasx; this.model = s_model; this.chiphisx = f_chiphisx; this.thoigiansx = i_thoigiansx; this.so = 0;
public XeGa( ) { } public XeGa(String s_nhasx, String s_model, f_chiphisx, int i_thoigiansx);{ } public float tinhGiaBan( ) { return 2.5 * chiphisx; }
}
Ba tiền tố trong kế thừa
o public o final: Lớp hằng, lớp không thể tạo dẫn xuất (không
thể có con).
o abstract: Lớp trừu tượng
Không có khai báo các thành phần và các phương
thức.
Lớp dẫn xuất sẽ khai báo, cài đặt cụ thể các thuộc
tính, phương thức của lớp trừu tượng.
Lớp trừu tượng
System.out.println(“Day la con meo”);
public void hienThi(){ }
System.out.println(“Day la con cho”);
public void hienThi(){ }
abstract class DongVat { abstract void hienThi(); } public class ConMeo extends DongVat{ } public class ConCho extends DongVat{ }
Lớp trừu tượng
o Các phương thức được khai báo dùng các tiền tố private và static thì không được khai báo là trừu tượng abstract.
o Tất cả các lớp kế thừa từ lớp trù tượng phải định nghĩa lại tất cả các phương thức từ lớp trừu tượng.
Phương thức Finalize
o Java không có kiểu dữ liệu con trỏ như trong C. o Java có một trình dọn dẹp hệ thống sẽ dọn dẹp vùng nhớ cấp phát cho các đối tượng trước khi hủy một đối tượng. o Phương thức finalize() là một phương thức đặc biệt được cài đặt sẵn cho các lớp. Trình dọn dẹp hệ thống sẽ gọi phương thức này trước khi hủy một đối tượng.
// Khai báo các thuộc tính public void method_1( ) { // … } protected void finalize(){
}
class A{ // Có thể dùng để đóng tất cả các kết nối // vào cơ sở dữ liệu trước khi hủy đối tượng. }
Các thành phần khác
o Gói (package) o Giao diện (interface)
Ví dụ về đa hình
return 0.0;
public double dienTich() { } public abstract String getName();
public abstract class Shape extends Object{ }
Ví dụ về đa hình
setPoint( xCoordinate, yCoordinate );
x = xCoordinate; y = yCoordinate;
return "[" + x + ", " + y + "]";
protected int x, y; // Tọa độ x, y của 1 điểm public Point( ){ setPoint( 0, 0 ); } public Point(int xCoordinate, int yCoordinate){ } public void setPoint( int xCoordinate, int yCoordinate ){ } public String toString(){ }
return "Point";
public class Point extends Shape{ //cài đặt phương thức trừu tượng của lớp cha public String getName(){ } }
Ví dụ về đa hình
setRadius( 0 );
radius = ( circleRadius >= 0 ? circleRadius:0 );
return "Center = " + super.toString() + "; Radius = " + radius; }
return "Circle";
public class Circle extends Point { protected double radius; public Circle(){ //ngầm gọi đến constructor của lớp cha } public Circle( double circleRadius, int xCoordinate, int yCoordinate ){ super( xCoordinate, yCoordinate ); // gọi constructor của lớp cha setRadius( circleRadius ); } public void setRadius( double circleRadius ){ } public String toString(){ public String getName() // trả về tên của shape{ } }

