Chương 3 Lập trình Hướng đối tượng với Java (tt)
Ầ
TR N MINH THÁI Email: minhthai@huflit.edu.vn Website: www.minhthai.edu.vn
Cập nhật: 02 tháng 07 năm 2016
Nội dung
1. Vấn đề tái sử dụng code
2. Kế thừa trong Java
3. Tính đa hình trong Java
4. Cài đặt interface trong Java
5.
Lập trình tổng quát
#2
Vấn đề tái sử dụng code
• Lập trình cấu trúc: chương trình con
• OOP: nhiều loại đối tượng có thuộc tính, hành vi tương tự nhau
tái sử dụng các lớp đã viết
• Trong một lớp vẫn tái sử dụng phương thức
• Ưu điểm:
#3
• Giảm chi phí
• Nâng cao khả năng bảo trì và khả năng mô hình hóa
Các hình thức tái sử dụng code
• Sao chép lớp cũ thành 1 lớp khác
Hạn chế: Dư thừa, khó quản lý khi có thay đổi
• Kết hợp: Lớp mới là tập hợp hoặc sử dụng các lớp đã có
• Kế thừa: Lớp mới phát triển thêm các thuộc tính hoặc phương
thức từ lớp đã có
#4
Kết hợp (Aggregation)
• Thành phần lớp mới chứa các đối tượng của lớp cũ
#5
• Lớp mới: Lớp chứa/Lớp toàn thể
• Ví dụ:
• Lớp cũ: Lớp thành phần
• Lớp cũ: Điểm (Point)
• Lớp chứa tái sử dụng các thuộc tính và phương thức của lớp
thành phần thông qua đối tượng
• Lớp mới: Tam giác (Triangle) có 3 điểm
Ký hiệu Kết hợp
• 1 số nguyên dương (1, 2, 3...)
• Dải số (0..1, 1..n)
• Bất kỳ giá trị nào: *
• Không ghi: mặc định là 1
#6
Ví dụ Lớp ToaDoDiem
#7
Ví dụ Lớp ToaDoDiem (tt)
#8
Ví dụ Lớp TamGiac
#9
Ví dụ Lớp TamGiac (tt)
#10
Bài tập 1
Xây dựng một trò chơi xúc xắc. Cách chơi như sau:
• Mỗi hạt xúc xắc được gieo sẽ có giá trị ngẫu nhiên 1..6
• Hai người lần lượt gieo 1 hạt xúc xắc
• Sau mỗi lượt gieo, số điểm của lượt đó được tích lũy vào số
điểm của người chơi
• Sau các lượt gieo theo quy định, người thắng cuộc là người có
tổng số điểm lớn hơn
Hãy xác định các lớp cần thiết và cài đặt
#11
Xác định lớp
• Xúc xắc (XucXac)
#12
• Thuộc tính: giá trị của mặt (giaTri)
• Người chơi (NguoiChoi)
• Phương thức: sinh ngẫu nhiên giá trị mặt của xúc xắc (sinhGiaTri())
• Thuộc tính: tên (ten), điểm (diem)
• Phương thức: gieo xúc xắc (gieoXucXac())
Xác định lớp
• Trận đấu (TranDau)
#13
chơi (soVong), người thắng cuộc (nguoiThang)
• Thuộc tính: xúc xắc (xucXac), 2 người chơi (nguoiChoi), số vòng
tin (hienThi()), thực hiện trận đấu (thucHienTranDau())
• Phương thức: bắt đầu (batDau()), kết thúc (ketThuc), hiển thị thông
Xác định lớp
#14
Lớp XucXac
#15
public class XucXac { private int giaTri;
public int getGiaTri() { return giaTri; } public void setGiaTri(int giaTri) { this.giaTri = giaTri; } public XucXac(){ giaTri=1; } public void sinhGiaTri(){ Random random = new Random(); this.giaTri=random.nextInt(5) + 1; } }
Lớp NguoiChoi
#16
public class NguoiChoi { private String ten; private int diem; public String getTen() { return ten; } public void setTen(String ten) { this.ten = ten; } public int getDiem() { return diem; } public void setDiem(int diem) { this.diem = diem; }
Lớp NguoiChoi
#17
public NguoiChoi(String ten){ this.ten=ten; this.diem=0; } public void gieoXucXac(XucXac xucXac){ Scanner sn = new Scanner(System.in); System.out.print(">>> Hay nhan Enter
de gieo xuc xac...");
sn.nextLine(); xucXac.sinhGiaTri(); this.diem+=xucXac.getGiaTri(); System.out.println("-- Diem: "
+ this.diem);
} }
Lớp TranDau
#18
public class TranDau { private XucXac xucXac; private NguoiChoi nguoiChoi1; private NguoiChoi nguoiChoi2; private NguoiChoi nguoiThang; private int soVong;
public TranDau(String ten1, String ten2,
int soVong){
this.nguoiChoi1 = new NguoiChoi(ten1); this.nguoiChoi2 = new NguoiChoi(ten2); this.xucXac = new XucXac(); this.soVong = soVong; }
Lớp TranDau
#19
public void batDau(){ System.out.println("Tran dau bat dau..."); for(int i=1; i<=this.soVong; i++){ System.out.printf("***** Vong %d *****\n",i); System.out.println(">" + nguoiChoi1.getTen()
+ " gieo xuc xac");
nguoiChoi1.gieoXucXac(xucXac);
System.out.println(">" + nguoiChoi2.getTen()
+ " gieo xuc xac");
nguoiChoi2.gieoXucXac(xucXac);
} }
Lớp TranDau
#20
public void ketThuc(){ int diem1= nguoiChoi1.getDiem(); int diem2=nguoiChoi2.getDiem(); if(diem1>diem2) this.nguoiThang=this.nguoiChoi1; else if(diem2>diem1) this.nguoiThang=this.nguoiChoi2; }
Lớp TranDau
#21
public void hienThi(){ System.out.println("* Ket qua tran dau *"); System.out.printf("- Diem cua %s: %d",
nguoiChoi1.getTen(), nguoiChoi1.getDiem());
System.out.printf("- Diem cua %s: %d",
nguoiChoi2.getTen(), nguoiChoi2.getDiem());
if(nguoiThang!=null)
System.out.printf("Nguoi thang cuoc: %s",
nguoiThang.getTen());
else
System.out.println("Tran dau hoa!!!");
} public void thucHienTranDau(){ batDau(); ketThuc(); hienThi(); } }
#22
public class XucXacTest { public static void main(String []args){ String ten1, ten2; int soVong; Scanner sn = new Scanner(System.in);
System.out.print("> Ten nguoi choi 1: "); ten1=sn.nextLine(); System.out.print("> Ten nguoi choi 2: "); ten2=sn.nextLine(); System.out.print("> So vong dau: "); soVong=sn.nextInt();
TranDau tranDau = new
TranDau(ten1, ten2, soVong);
tranDau.thucHienTranDau(); } }
Bài tập 2
Hãy viết lại các lớp trong Bài tập 1 để thoả yêu cầu sau:
• Có thêm thuộc tính soBanThang ghi lại số bàn thắng
• Giả sử 2 người chơi phải chơi 3 ván đấu. Nếu người chơi nào
thắng trước 2 ván thì người chơi đó thắng cả trận đấu
#23
Kế thừa (Inheritance)
• Ngoài việc nhóm các đối tượng có cùng tập thuộc tính/hành vi lại với nhau thành một lớp, con người thường nhóm các đối tượng có cùng một số thuộc tính/ hành vi
#24
thành các nhóm nhỏ hơn tuỳ theo loại xe (xe ô tô, xe tải, ...)
• Ví dụ: nhóm tất cả xe chạy bằng động cơ thành một nhóm, rồi phân
Kế thừa
• Mỗi nhóm con là một lớp các đối tượng tương tự, nhưng giữa
các nhóm con có chung một số đặc điểm
• Quan hệ giữa các nhóm con với nhóm lớn được gọi là quan hệ
“là một” (is-a)
#25
Kế thừa
• Ví dụ:
o Một cái xe ô tô “là một” xe động cơ
o Một cái xe tải “là một” xe động cơ
o Một cái xe máy “là một” xe động cơ
#26
Dùng cấu trúc hướng đối tượng để định nghĩa quan hệ “là
(cid:0)
một”
Kế thừa
• Các đối tượng được nhóm lại thành một lớp thì có cùng tập
thuộc tính và hành vi
#27
• Mọi đối tượng xe động cơ có cùng tập thuộc tính và hành vi
Mọi đối tượng xe tải có cùng tập thuộc tính và hành vi
(cid:0)
Kế thừa
• Mối liên kết giữa các lớp trong quan hệ “là một” xuất phát từ thực
tế rằng:
#28
• Các lớp con cũng có mọi thuộc tính/ hành vi của lớp cha
• và cộng thêm các thuộc tính/ hành vi khác
Kế thừa
• Lớp cha – superclass (hoặc lớp cơ sở - base class)
#29
• Lớp tổng quát hơn trong mối quan hệ “là một”
• Các đối tượng thuộc lớp cha có cùng tập thuộc tính và hành vi
Kế thừa
• Lớp con – subclass (hoặc lớp dẫn xuất – derived class)
#30
• Lớp cụ thể hơn trong một quan hệ “là một”
• Các đối tượng thuộc lớp con có cùng tập thuộc tính và hành vi (do kế thừa từ lớp cha), kèm thêm tập thuộc tính và hành vi của riêng lớp con
Kế thừa
• Quan hệ “là một” còn gọi là sự kế thừa (inheritance)
• Ta nói rằng lớp con “kế thừa từ” lớp cha, hoặc lớp con “được
dẫn xuất từ” lớp cha
#31
Kế thừa là quá trình tạo nên lớp mới bằng cách dẫn xuất từ
lớp cũ
(cid:0)
Kế thừa
• Ưu điểm của việc kế thừa
#32
• Tiết kiệm thời gian và công sức
• Tái sử dụng lại những lớp có sẵn
• Giảm lượng code phải thiết kế, viết, kiểm tra
• Tránh trùng lắp code
• Rút ngắn thời gian giúp LTV tập trung vào mục tiêu
• Giúp phân loại và thiết kế lớp dễ dàng, dễ quản lý
Kế thừa
• Phân loại
#33
• Đơn kế thừa (single inheritance): chỉ có một lớp cha
• Đa kế thừa (multiple inheritance): có nhiều lớp cha
Kế thừa
• Tạo lớp mới bằng cách phát triển từ lớp đã có
#34
• Lớp mới kế thừa những thành viên đã có trong lớp cũ
• Lớp cũ: Lớp cha (superclass), lớp cơ sở (baseclass)
• Ví dụ:
• Lớp mới: Lớp con (subclass), lớp dẫn xuất (derived class)
• Lớp cũ: Điểm (ToaDoDiem)
• Kết hợp: Tam giác (TamGiac) có 3 điểm
• Kế thừa: Tam giác vuông (TamGiacVuong)
Kết hợp vs Kế thừa
ế ừ K th a
ế ợ K t h p
ử ụ
ử ụ
ồ
ồ Tái s d ng mã ngu n
Tái s d ng mã ngu n
ố ượ
thông qua l pớ
thông qua đ i t
ng
ệ
ạ
ộ
ệ
ầ
ộ
Quan h “là m t lo i”
Quan h “là m t ph n”
ụ
ụ
ỉ
Ví d : Tam giác vuông là
Ví d : Tam giác có 3 đ nh
ạ
ộ
m t lo i tam giác
#35
Ký hiệu kế thừa
#36
Sơ đồ quan hệ đối tượng (Object Relationship Diagram – ORD)
• Thể hiện
#37
sở và lớp dẫn xuất
• Sự khác nhau giữa lớp cơ
lớp dẫn xuất
• Sự khác nhau giữa các
Sơ đồ quan hệ đối tượng
• Đối với những lớp dẫn xuất, chỉ cần liệt kê các thuộc tính/ hành
vi mà lớp cơ sở không có
ơ ồ
ơ
ả • Đ n gi n hoá s đ
ạ
ấ
• Nh n m nh
các
ể
đi m khác bi
ệ t
#38
Cây kế thừa
• Các quan hệ kế thừa luôn được biểu diễn với các lớp dẫn xuất đặt dưới lớp cơ sở để nhấn mạnh bản chất phả hệ của quan hệ
#39
Cây kế thừa
Kế thừa phần lớn các thành viên dữ liệu và phương thức của lớp cơ sở
(ngoại trừ constructor, destructor)
Lớp dẫn xuất
Có thể bổ sung thêm các thành viên dữ liệu mới và các phương thức mới
Lớp cơ sở trực tiếp
Class A
Lớp cơ sở
Class B
Lớp cơ sở gián tiếp
Class C
#40
Nhận biết kế thừa?
class AB
class A
class A
class B
class B
#41
Định nghĩa lớp kế thừa
• Cú pháp
class SubClass extends SuperClass{
Định nghĩa SubClass
}
• Lớp con truy cập tới thành viên lớp cha qua từ khóa super
• Mọi lớp trong Java đều kế thừa từ lớp tổng quát Object
• Lớp Object cung cấp một số phương thức toString(), equals()
• Java chỉ cho phép đơn kết thừa: một lớp chỉ có thể kế thừa từ
duy nhất 1 lớp khác
#42
Chỉ định truy cập
• Chỉ định truy cập lớp:
#43
• public: cho phép lớp con kế thừa nằm ở bất kỳ đâu
• Chỉ định truy cập thành viên:
• Không chỉ định: chỉ cho phép lớp con kế thừa nằm cùng gói
• public, protected: cho phép lớp con ở bất kỳ đâu được kế thừa thuộc tính/phương thức này, được truy cập vào thuộc tính/thành viên tương ứng trên lớp cha
được truy cập tới thuộc tính/thành viên tương ứng của lớp cha
• Không chỉ định: chỉ cho phép lớp con ở cùng gói được kế thừa và
• private: lớp con không được kế thừa thuộc tính/phương thức này, không được truy cập vào thuộc tính/thành viên tương ứng trên lớp cha
Ví dụ chỉ định public cho class cha
#44
Ví dụ class con cùng gói
#45
Ví dụ class con khác gói
#46
Ví dụ không chỉ định public class cha
ươ
ự ỉ
ị
• Cùng gói: t
ng t
ch đ nh public
ế ừ
• Khác gói: không cho k th a!!!
#47
Khởi tạo đối tượng trong kế thừa
• Lớp con không kế thừa phương thức khởi tạo của lớp cha
• Lớp cha phải được khởi tạo trước lớp con
• Các phương thức khởi tạo của lớp con tự động gọi phương
thức khởi tạo mặc định của lớp cha (nếu có)
• Nếu lớp cha không có phương thức khởi tạo mặc định thì phải
gọi phương thức khởi tạo khác mặc định của lớp cha
• Cú pháp: super(parameterList)
#48
Thứ tự khởi tạo và huỷ trong kế thừa
#49
A
B
C
Ví dụ khởi tạo đối tượng trong kế thừa
#50
Ví dụ khởi tạo đối tượng trong kế thừa
#51
Ví dụ khởi tạo đối tượng trong kế thừa (tt)
#52
Ví dụ khởi tạo đối tượng trong kế thừa (tt)
#53
Đối tượng cha và con
• Khi tạo đối tượng con, đối tượng cha được tạo ra độc lập
• Đối tượng con có tham chiếu tới đối tượng cha qua từ khóa
#54
super (tham chiếu này là private)
• Trong lớp con, nếu truy cập tới thuộc tính/phương thức của cha thì truy cập đó có được là qua từ khóa super (tường minh, hoặc không tường minh), đối tượng con được xem như đối tượng thuộc lớp cha (upcasting)
Ví dụ
Thiết kế các lớp cần thiết để quản lý thông tin của một giảng viên và sinh viên.
• Đối với sinh viên gồm các thông tin và hành vi:
#55
• Họ tên
• Tuổi
• Tên trường học
• Số tín chỉ đã tích luỹ
• Cập nhật số tín chỉ
• Hiển thị thông tin
Ví dụ (tt)
• Đối với giảng viên gồm các thông tin và hành vi:
#56
• Họ tên
• Tuổi
• Tên trường công tác
• Học vị
• Hệ số lương
• Mức lương cơ bản
Giả sử không dùng kế thừa
#57
Lớp SinhVien
#58
public class SinhVienKhongKeThua { private String hoTen; private int tuoi; private String tenTruong; private int tinChiTichLuy;
public String getHoTen() { return hoTen; } public void setHoTen(String hoTen) { this.hoTen = hoTen; } public int getTuoi() { return tuoi; } public void setTuoi(int tuoi) { this.tuoi = tuoi; }
#59
public String getTenTruong() { return tenTruong; } public void setTenTruong(String tenTruong) { this.tenTruong = tenTruong; } public int getTinChiTichLuy() { return tinChiTichLuy; } public void setTinChiTichLuy(int tinChiTichLuy) { this.tinChiTichLuy = tinChiTichLuy; } public SinhVienKhongKeThua(String hoTen,
int tuoi, String tenTruong) {
this.setHoTen(hoTen); this.setTuoi(tuoi); this.setTenTruong(tenTruong); this.setTinChiTichLuy(0); }
public void capNhatTinChi(int soLuong){ #60 this.setTinChiTichLuy(this.getTinChiTichLuy()
+ soLuong);
} public void hienThiThongTinSinhVien() { System.out.println("- Ho va ten: " + this.getHoTen());
System.out.println("- Tuoi: " +
this.getTuoi());
System.out.println("- Ten truong: " +
this.getTenTruong());
System.out.println("- So tin chi tich luy: "
+ this.getTinChiTichLuy());
} }
Lớp GiangVien
#61
public class GiangVienKhongKeThua { private String hoTen; private int tuoi; private String tenTruong; private String hocVi; private double heSoLuong; private int luongCoBan;
public String getHoTen() { return hoTen; } public void setHoTen(String hoTen) { this.hoTen = hoTen; } public int getTuoi() { return tuoi; }
#62
public String getTenTruong() { return tenTruong; } public void setTenTruong(String tenTruong) { this.tenTruong = tenTruong; } public String getHocVi() { return hocVi; } public void setHocVi(String hocVi) { this.hocVi = hocVi; } public double getHeSoLuong() { return heSoLuong; } public void setHeSoLuong(double heSoLuong) { this.heSoLuong = heSoLuong; }
#63
public int getLuongCoBan() { return luongCoBan; } public void setLuongCoBan(int luongCoBan) { this.luongCoBan = luongCoBan; } public GiangVienKhongKeThua(String hoTen,
int tuoi, String tenTruong, String hocVi, int heSoLuong, int luongCoBan){
this.setHoTen(hoTen); this.setTuoi(tuoi); this.setTenTruong(tenTruong); this.setHocVi(hocVi); this.setHeSoLuong(heSoLuong); this.setLuongCoBan(luongCoBan); }
#64
public void hienThiThongTinGiangVien(){ System.out.println("- Ho va ten: "
+ this.getHoTen());
System.out.println("- Tuoi: "
+ this.getTuoi());
System.out.println("- Ten truong: "
+ this.getTenTruong()); System.out.println("- Hoc vi: "
+ this.getHocVi());
System.out.println("- He so luong: "
+ this.getHeSoLuong());
System.out.println("- Luong co ban: "
+ this.getLuongCoBan());
} }
Sử dụng lớp kế thừa
#65
Sử dụng lớp kế thừa
Tách những thông tin chung thành 1 lớp mới: Lớp người (ConNguoi) gồm các thông tin và hành vi nói chung
• Tên
• Tuổi
• Nghề nghiệp
• Hiển thị thông tin
#66
Cây kế thừa
#67
Lớp ConNguoi
#68
public class ConNguoi { private String hoTen; private int tuoi; private String tenTruong; private String ngheNghiep;
public String getHoTen() { return hoTen; } public void setHoTen(String hoTen) { this.hoTen = hoTen; } public int getTuoi() { return tuoi; } public void setTuoi(int tuoi) { this.tuoi = tuoi; }
#69
public String getNgheNghiep() { return ngheNghiep; }
public void setNgheNghiep(String ngheNghiep) { this.ngheNghiep = ngheNghiep; } public String getTenTruong() { return tenTruong; }
public void setTenTruong(String tenTruong) { this.tenTruong = tenTruong; }
public ConNguoi(String hoTen, int tuoi,
String tenTruong) { this.setHoTen(hoTen); this.setTuoi(tuoi); this.setTenTruong(tenTruong); this.setNgheNghiep(""); }
#70
public void hienThiThongTinNguoi() { System.out.println("- Ho va ten: " +
this.getHoTen());
System.out.println("- Tuoi: " +
this.getTuoi());
System.out.println("- Nghe nghiep: " + this.getNgheNghiep());
System.out.println("- Ten truong: " + this.getTenTruong());
}
Lớp SinhVien
#71
public class SinhVien extends ConNguoi{ private int tinChiTichLuy;
public int getTinChiTichLuy() { return tinChiTichLuy; }
public void setTinChiTichLuy(int tinChiTichLuy){ this.tinChiTichLuy = tinChiTichLuy; }
public SinhVien(String hoTen, int tuoi,
super(hoTen, tuoi, tenTruong); super.setNgheNghiep("Sinh vien"); this.setTinChiTichLuy(0); }
#72 String tenTruong) {
public void capNhatTinChi(int soLuong) { this.setTinChiTichLuy(this.getTinChiTichLuy()
+ soLuong);
}
public void hienThiThongTinSinhVien() { super.hienThiThongTinNguoi(); System.out.println("- So tin chi da tich luy: "
+ this.getTinChiTichLuy());
}
public class SinhVienTest { public static void main(String []args) { System.out.println("*** Tao doi tuong
con nguoi:");
ConNguoi nguoi = new ConNguoi("An", 17, ""); System.out.println("*** Thong tin vua tao:"); nguoi.hienThiThongTinNguoi(); System.out.println("*** An tro thanh
#73
sinh vien DH ABC:");
SinhVien sv = new SinhVien(nguoi.getHoTen(),
nguoi.getTuoi(), "Dai hoc ABC"); System.out.println("*** Thong tin sinh vien:"); sv.hienThiThongTinSinhVien(); System.out.println("*** An hoc xong mon
OOP in Java (4 tin chi)");
System.out.println("*** Cap nhat so tin chi
cho An:");
sv.capNhatTinChi(4); System.out.println("*** Thong tin sinh vien:"); sv.hienThiThongTinSinhVien(); } }
!!! Tương tự cho lớp GiangVien
Che thuộc tính
Trong lớp con khai báo một thuộc tính có tên giống lớp cha thì trong lớp con thuộc tính của lớp cha bị che đi
• Để truy cập tới thuộc tính trên lớp cha dùng từ khóa super
• Để phân biệt trong lớp con, dùng từ khóa this
#74
Ví dụ
#75
Ví dụ
#76
Nạp chồng và ghi đè phương thức
• Lớp con có thể định nghĩa lại các phương thức kế thừa được
từ lớp cha:
#77
• Ghi đè (overriding): Cùng mẫu với phương thức của lớp cha
thức và thay đổi danh sách tham số
• Nạp chồng phương thức (overloading): Giữ nguyên tên phương
!!! Giữ nguyên kiểu dữ liệu trả về của lớp cha
Ví dụ 1
#78
Ví dụ 1 (tt)
#79
Ví dụ 2
#80
Ví dụ 2 (tt)
#81
Cấm ghi đè phương thức
Trong một số trường hợp cần cấm ghi đè phương thức khi kế thừa:
• Đảm bảo tính đúng đắn: việc ghi đè phương thức có thể gây ra
sự sai lạc về ý nghĩa
• Tính hiệu quả: giảm thời gian xử lý lời gọi phương thức
định nghĩa phương thức với từ khóa final
#82
Ví dụ
#83
Lỗi
#84
Tính đa hình trong Java
Tính đa hình trong Java
• Trừu tượng hoá
• Hiện thực đa hình trong Java
#85
Trừu tượng hoá
• Loại bỏ những thông tin cụ thể, giữ lại các thông tin chung
• Mức độ trừu tượng hoá được thể hiện trên cây kế thừa
#86
Định nghĩa lớp trừu tượng
• Sử dụng từ khoá abstract cho phương thức trừu tượng
• Bổ sung từ khoá abstract phía trước class
#87
public abstract class ClassName{ Khai báo thuộc tính; public abstract dataType methodName(listParameter); Định nghĩa các phương thức khác; }
Đặc điểm lớp trừu tượng
• Phương thức trừu tượng không được phép định nghĩa cụ thể
tại lớp cha (kết thúc khai báo phương thức bằng dấu ;)
• Lớp con kế thừa từ lớp trừu tượng phải định nghĩa nội dung
của phương thức trừu tượng
• Chỉ định truy cập không được chặt hơn lớp cha
• Không được tạo đối tượng từ lớp trừu tượng
• Lớp trừu tượng vẫn có phương thức khởi tạo
#88
Ví dụ
• Cho lớp hình tròn (HinhTron) gồm:
#89
• Toạ độ tâm: x, y
• Bán kính: banKinh
• Tính diện tính: tinhDienTich()
2 lớp cùng chung: - x, y,
• Cho lớp hình chữ nhật (HinhChuNhat) gồm:
-
tinhDienTich()
• Toạ độ tâm: x, y
• Kích thước: chieuNgang, chieuDung
• Tính diện tích: tinhDienTich()
Ví dụ (tt)
• Công thức tinhDienTich() chung cho cả hình tròn và hình chữ
nhật: rỗng phương thức trừu tượng
#90
public abstract double tinhDienTich();
Lớp trừu tượng
public abstract class HinhHoc
Ví dụ (tt)
#91
Lớp HinhHoc
#92
Lớp HinhTron
#93
Lớp HinhChuNhat
#94
Lớp HinhHocTest
#95
#96
Giao diện (Interface)
Giao diện
• Sử dụng trong trường hợp đa kế thừa (kế thừa từ nhiều lớp)
• Giao diện chỉ quy định các phương thức phải có, nhưng không
định nghĩa cụ thể
Tách rời đặc tả mức trừu tượng và triển khai cụ thể
Đảm bảo tính cộng tác trong phát triển phần mềm
Các giao diện có thể kế thừa nhau
• • Cú pháp
• 11
• Modifier interface InterfaceName {
• //Declare constants
• //Declare methods
• }
#97
Giao diện
• Cú pháp
Modifier interface InterfaceName { Khai báo các hằng số Khai báo các phương thức }
#98
Triển khai giao diện
Modifier class ClassName implements
Interface1, Interface2 {
1. Định nghĩa lớp
2. Định nghĩa tất cả các phương thức
của Interface1 và Interface2
}
#99
Kế thừa và triển khai giao diện
#100
Modifier class SubClass extends SuperClass implements Interface1, Interface2 { Định nghĩa SubClass kế thừa từ SuperClass Định nghĩa tất cả phương thức của Interface1 và Interface2 }
Giao diện vs Trừu tượng
ừ ượ
Giao di nệ
Tr u t
ng
ỉ ượ
c phép có thành viên
ể
ộ
Có th có thu c tính
Ch đ h ngằ
ừ
ng th c là tr u ậ
ươ ớ
ỉ
ứ ị ng v i ch đ nh truy c p
ừ ứ ươ ng th c tr u ươ ể ng ng, có th có ph
ọ M i ph ượ t public
Ngoài ph ượ t ứ th c riêng
ươ
ở
ứ ng th c kh i
ươ
ứ
Có ph
ở ạ ng th c kh i t o
Không có ph t oạ
ỉ
ộ ớ ề
ừ ượ
ể ể M t l p có th tri n khai ệ nhi u giao di n
ộ ớ M t l p ch có th k th a ừ ộ ớ m t l p tr u t t
ể ế ừ ng
ồ
ử ụ
ồ
ử ụ Không tái s d ng mã ngu n
Có tái s d ng mã ngu n
#101
Ví dụ
#102
Giao diện HinhHoc
#103
Lớp HinhTron
#104
Lớp HinhChuNhat
#105
Đa hình (Polymorphism)
Nhiều hình thức thực hiện một hành vi, nhiều kiểu tồn tại của một đối tượng
• Đa hình phương thức: chồng phương thức, ghi đè phương
thức
• Đa hình đối tượng: nhìn nhận đối tượng theo nhiều kiểu khác
nhau
#106
Upcasting và Downcasting
• Upcasting: đối tượng lớp con được nhìn nhận như đối tượng
lớp cha: Thực hiện tự động
• Downcasting: đối tượng lớp cha được nhìn nhận như đối tượng
lớp con: Phải ép kiểu
#107
Ví dụ
#108
Toán tử instanceof
• Kiểm tra một đối tượng có phải đang là thể hiện của lớp hoặc
giao diện nào đó không: true hoặc false
• Cú pháp:
objectName instanceof ClassName
objectName instanceof InterfaceName
#109
Nạp chồng phương thức
• Nạp chồng phương thức (Overloading): giữ tên và giá trị trả về,
thay đổi đối số
• Ghi đè phương thức (Overriding): giữ nguyên tên, giá trị trả về
và đối số
#110
Nạp chồng phương thức
• Liên kết tĩnh: Khối mã lệnh của phương thức được xác định khi
dịch
• Liên kết động: Khối mã lệnh của hàm được xác định ghi
chương trình thực thi
• Liên kết lời gọi hàm: xác định địa chỉ trên bộ nhớ của khối mã
lệnh thực hiện phương thức khi có lời gọi
#111
!!!Nạp chồng phương thức: thực hiện liên kết động
Ghi đè phương thức equals()
• Không thể dùng toán tử so sánh == để so sánh 2 đối tượng
• Mọi lớp được kế thừa phương thức equals từ lớp Object định
nghĩa lại cho phù hợp
• Hai đối tượng bằng nhau khi thỏa mãn 2 điều kiện:
#112
• Cùng thuộc một lớp
• Giá trị của mọi thuộc tính là như nhau
!!!2 giá trị tham chiếu bằng nhau đối tượng bằng nhau
Ghi đè phương thức equals() cho lớp ConNguoi
#113
Ghi đè phương thức equals() cho lớp ConNguoi
#114
Lập trình tổng quát
• Xây dựng chương trình có thể làm việc với nhiều kiểu dữ liệu
khác nhau trên cùng thao tác xữ lý
#115
Cách thức lập trình tổng quát
#116
Cách thức lập trình tổng quát
#117
Q&A
#118