Bài giảng Lập trình hướng đối tượng - Bài 5: Kết tập và kế thừa

9/18/17  
Mục tiêu bài học  
n Giải thích về khái niệm tái sử dụng mã nguồn  
Bộ môn Công nghệ Phần mềm  
Viện CNTT & TT  
n Chỉ ra được bản chất, mô tả các khái niệm  
Trường Đại học Bách Khoa Hà Nội  
liên quan đến đến kết tập và kế thừa  
n So sánh kết tập và kế thừa  
n Biểu diễn được kết tập và kế thừa trên UML  
LẬP TRÌNH HƯỚNG ĐỐI TƯỢNG  
n Giải thích nguyên lý kế thừa và thứ tự khởi  
Bài 05. Kết tập và kế thừa  
tạo, hủy bỏ đối tượng trong kế thừa  
n Áp dụng các kỹ thuật, nguyên lý về kết tập  
và kết thừa trên ngôn ngữ lập trình Java  
2
Nội dung  
Nội dung  
1. Tái sử dụng mã nguồn  
2. Kết tập (Aggregation)  
3. Kế thừa (Inheritance)  
1. Tái sử dụng mã nguồn  
2. Kết tập (Aggregation)  
3. Kế thừa (Inheritance)  
3
4
1
9/18/17  
1. Tái sử dụng mã nguồn (2)  
1. Tái sử dụng mã nguồn (Re-usability)  
n Tái sử dụng mã nguồn: Sử  
dụng lại các mã nguồn đã  
viết  
n Các cách sử dụng lại lớp đã có:  
n
Sao chép lớp cũ thành 1 lớp khác à Dư thừa và  
khó quản lý khi có thay đổi  
n
Tạo ra lớp mới là sự tập hợp hoặc sử dụng các  
đối tượng của lớp cũ đã có à Kết tập  
(Aggregation)  
Tạo ra lớp mới trên cơ sở phát triển từ lớp cũ đã  
có à Kế thừa (Inheritance)  
n
Lập trình cấu trúc: Tái sử dụng  
hàm/chương trình con  
OOP: Khi mô hình thế giới thực,  
tồn tại nhiều loại đối tượng có  
các thuộc tính và hành vi tương  
tự hoặc liên quan đến nhau  
n
n
n
à Làm thế nào để tái sử dụng  
lớp đã viết?  
5
6
Nội dung  
Ưu điểm của tái sử dụng mã nguồn  
n Giảm thiểu công sức, chi phí  
n Nâng cao chất lượng phần  
1. Tái sử dụng mã nguồn  
2. Kết tập (Aggregation)  
3. Kế thừa (Inheritance)  
mềm  
n Nâng cao khả năng mô hình  
hóa thế giới thực  
n Nâng cao khả năng bảo trì  
(maintainability)  
7
8
2
9/18/17  
2. Kết tập  
2.1. Bản chất của kết tập  
n Ví dụ:  
Điểm  
n Kết tập (aggregation)  
n
n
Tạo ra các đối tượng của các lớp có sẵn trong  
lớp mới à thành viên của lớp mới.  
n
Tứ giác gồm 4 điểm  
à Kết tập  
n
Kết tập tái sử dụng thông qua đối tượng  
n Kết tập  
Quan hệ chứa/có ("has-  
n Lớp mới  
n
n
Lớp toàn thể (Aggregate/Whole),  
a") hoặc là một phần  
(is-a-part-of)  
n Lớp cũ  
n
Lớp thành phần (Part).  
9
10  
2.1. Bản chất của kết tập (2)  
2.2. Biểu diễn kết tập bằng UML  
n Sử dụng "hình thoi" tại đầu của  
n Lớp toàn thể chứa đối tượng  
lớp toàn thể  
của lớp thành phần  
n Sử dụng bội số quan hệ  
n
Là một phần (is-a-part of) của  
lớp toàn thể  
(multiplicity) tại 2 đầu  
n
n
n
n
1 số nguyên dương: 1, 2,...  
Dải số (0..1, 2..4)  
*: Bất kỳ số nào  
n
Tái sử dụng các thành phần dữ  
liệu và các hành vi của lớp thành  
phần thông qua đối tượng thành  
phần  
Không có: Mặc định là 1  
1
4
n Tên vai trò (rolename)  
TuGiac  
Diem  
n
Nếu không có thì mặc định là  
tên của lớp (bỏ viết hoa chữ  
cái đầu)  
11  
12  
3
9/18/17  
Ví dụ  
2.3. Minh họa trên Java  
class Diem {  
private int x, y;  
public Diem(){}  
public Diem(int x, int y) {  
this.x = x; this.y = y;  
}
public void setX(int x){ this.x = x; }  
public int getX() { return x; }  
public void printDiem(){  
System.out.print("(" + x + ", "  
+ y + ")");  
}
13  
}
14  
class TuGiac {  
1
4
public class Test {  
private Diem d1, d2;  
private Diem d3, d4;  
TuGiac  
Diem  
public static void main(String arg[])  
{
public TuGiac(Diem p1, Diem p2,  
Diem d1 = new Diem(2,3);  
Diem d2 = new Diem(4,1);  
Diem d3 = new Diem (5,1);  
Diem d4 = new Diem (8,4);  
Diem p3, Diem p4){  
d1 = p1; d2 = p2; d3 = p3; d4 = p4;  
}
public TuGiac(){  
d1 = new Diem();  
d2 = new Diem(0,1);  
TuGiac tg1 = new TuGiac(d1, d2, d3, d4);  
d3 = new Diem (1,1); d4 = new Diem (1,0);  
TuGiac tg2 = new TuGiac();  
}
tg1.printTuGiac();  
tg2.printTuGiac();  
public void printTuGiac(){  
d1.printDiem(); d2.printDiem();  
d3.printDiem(); d4.printDiem();  
System.out.println();  
}
}
}
15  
16  
}
4
9/18/17  
Cách cài đặt khác  
Ví dụ khác về Kết tập  
1
4
TuGiac  
Diem  
class TuGiac {  
n Một trò chơi gồm 2 đối thủ, 3 quân súc sắc  
private Diem[] diem = new Diem[4];  
public TuGiac(Diem p1, Diem p2,  
và 1 trọng tài.  
Diem p3, Diem p4){  
diem[0] = p1; diem[1] = p2;  
diem[2] = p3; diem[3] = p4;  
n Cần 4 lớp:  
n
n
n
n
Người chơi (Player)  
Súc sắc (Die)  
Trọng tài (Arbitrator)  
Trò chơi (Game)  
}
public void printTuGiac(){  
diem[0].printDiem(); diem[1].printDiem();  
diem[2].printDiem(); diem[3].printDiem();  
System.out.println();  
à Lớp Trò chơi là lớp kết tập của 3 lớp còn lại  
}
}
17  
18  
Game  
2.4. Thứ tự khởi tạo trong kết tập  
Die  
3
…
- value : int  
…
+ throw()  
n Khi một đối tượng được tạo mới, các thuộc  
tính của đối tượng đó đều phải được khởi tạo  
và gán những giá trị tương ứng.  
Player  
Arbitrator  
- name : String  
- points : int  
2
n Các đối tượng thành phần được khởi tạo  
- name : String  
trước  
+ throwDie()  
+ countingPoints()  
class Game  
{
à Các phương thức khởi tạo của các lớp của  
các đối tượng thành phần được thực hiện  
trước  
Die die1, die2, die3;  
Player player1, player2;  
Arbitrator arbitrator1;  
...  
19  
}
20  
5
9/18/17  
public class PhongBan {  
private String tenPhongBan; private byte soNhanVien;  
public static final SO_NV_MAX = 100;  
private NhanVien[] dsnv;  
public boolean themNhanVien(NhanVien nv){  
if (soNhanVien < SO_NV_MAX) {  
dsnv[soNhanVien] = nv; soNhanVien++;  
return true;  
Bài tập:  
n Viết mã nguồn cho lớp PhongBanvới các thuộc tính và  
phương thức như biểu đồ trên cùng phương thức khởi tạo  
với số lượng tham số cần thiết, biết rằng:  
n
n
n
Việc thêm/xóa nhân viên được thực hiện theo cơ chế của  
stack  
tongLuong()trả về tổng lương của các nhân viên trong  
phòng.  
inTTin() hiển thị thông tin của phòng và thông tin của các  
nhân viên trong phòng.  
PhongBan  
} else return false;  
}
NhanVien  
-tenNhanVien:String  
public NhanVien xoaNhanVien(){  
if (soNhanVien > 0) {  
1
1..*  
-tenPhongBan:String  
-heSoLuong:double  
-soNhanVien:byte  
NhanVien tmp = dsnv[soNhanVien-1];  
dsnv[soNhanVien-1] = null; soNhanVien--;  
return tmp;  
+LUONG_CO_BAN:double=750.000  
+LUONG_MAX:double=20.000.000  
+SO_NV_MAX:byte = 100  
+themNV(NhanVien):boolean  
+xoaNV():NhanVien  
+tongLuong():double  
+inTTin()  
+tangLuong(double):boolean  
+tinhLuong():double  
+inTTin()  
} else return null;  
}
21  
22  
// (cont)...  
// (cont.)  
public PhongBan(String tenPB){  
dsnv = new NhanVien[SO_NV_MAX];  
tenPhongBan = tenPB; soNhanVien = 0;  
}
public double tongLuong(){  
double tong = 0.0;  
Thảo luận  
Trong ví dụ trên  
n Lớp cũ? Lớp mới?  
for (int i=0;i<soNhanVien;i++)  
tong += dsnv[i].tinhLuong();  
return tong;  
n
Lớp cũ: NhanVien  
Lớp mới: PhongBan  
n
}
n Lớp mới tái sử dụng lớp cũ thông qua?  
public void inTTin(){  
System.out.println("Ten phong: "+tenPhong);  
System.out.println("So NV: "+soNhanVien);  
System.out.println("Thong tin cac NV");  
for (int i=0;i<soNhanVien;i++)  
dsnv[i].inTTin();  
n
Mảng đối tượng của lớp NhanVien: dsnv  
n Lớp mới tái sử dụng được những gì của lớp  
cũ?  
n
tinhLuong() trong phương thức tongLuong()  
inTTin() trong phương thức inTTin()  
}
23  
24  
n
}
6
9/18/17  
Nội dung  
3.1. Tổng quan về kế thừa  
n Ví dụ:  
n
Điểm  
1. Tái sử dụng mã nguồn  
2. Kết tập (Aggregation)  
3. Kế thừa (Inheritance)  
n
Tứ giác gồm 4 điểm  
à Kết tập  
Tứ giác  
n
n
Hình vuông  
à Kế thừa  
25  
26  
3.1.1. Bản chất kế thừa  
3.1.1. Bản chất kế thừa (2)  
n Lớp con  
n Kế thừa (Inherit, Derive)  
n
Là một loại (is-a-kind-of) của lớp cha  
n
Tạo lớp mới bằng cách phát triển lớp đã có.  
n
Tái sử dụng bằng cách kế thừa các thành phần  
dữ liệu và các hành vi của lớp cha  
n
Lớp mới kế thừa những gì đã có trong lớp cũ và  
phát triển những tính năng mới.  
n
Chi tiết hóa cho phù hợp với mục đích sử dụng  
mới  
n Lớp cũ:  
Lớp cha (parent, superclass), lớp cơ sở (base  
class)  
n Lớp mới:  
Lớp con (child, subclass), lớp dẫn xuất (derived  
class)  
n
n
Extension: Thêm các thuộc tính/hành vi mới  
n
Redefinition (Method Overriding): Chỉnh sửa lại các  
hành vi kế thừa từ lớp cha  
n
27  
28  
7
9/18/17  
3.1.3. Kết tập và kế thừa  
3.1.2. Biểu diễn kế thừa trong UML  
n Sử dụng "tam giác rỗng" tại đầu Lớp cha  
n So sánh kết tập và kế thừa?  
n
Giống nhau  
n
Đều là kỹ thuật trong OOP để tái sử dụng mã nguồn  
Mammal  
n
Khác nhau?  
TuGiac  
Whale  
Horse  
Hinh  
Hinh  
Vuong  
Thang  
29  
30  
3.1.4. Cây phân cấp kế thừa  
(Inheritance hierarchy)  
Phân biệt kế thừa và kết tập  
A
Kế thừa  
Kết tập  
n Kế thừa tái sử dụng  
n
n
n
Cấu trúc phân cấp hình cây, biểu diễn mối  
quan hệ kế thừa giữa các lớp.  
Dẫn xuất trực tiếp  
n Kết tập tái sử dụng thông  
thông qua lớp.  
qua đối tượng.  
B
C
n
Tạo lớp mới bằng cách  
phát triển lớp đã có  
n
Tạo ra lớp mới là tập hợp  
các đối tượng của các lớp  
đã có  
n
B dẫn xuất trực tiếp từ A  
Vehicle  
n
Lớp con kế thừa dữ  
liệu và hành vi của lớp  
cha  
Dẫn xuất gián tiếp  
n
Lớp toàn thể có thể sử  
dụng dữ liệu và hành vi  
thông qua các đối tượng  
thành phần  
n
C dẫn xuất gián tiếp từ A  
Car  
Moto  
n Quan hệ "là một loại"  
("is a kind of")  
n Quan hệ "là một phần"  
n Ví dụ: Ô tô là một loại  
("is a part of")  
phương tiện vận tải  
SportCar  
Compact  
SportMoto  
n Ví dụ: Bánh xe là một  
31  
32  
phần của Ô tô  
8
9/18/17  
3.1.4. Cây phân cấp kế thừa (2)  
3.1.4. Cây phân cấp kế thừa (2)  
n Các lớp con có cùng lớp cha gọi là anh chị em  
Mọi lớp  
(siblings)  
đều kế thừa từ  
lớp gốc Object  
n Thành viên được kế thừa sẽ được kế thừa xuống dưới  
trong cây phân cấp à Lớp con kế thừa tất cả các lớp  
Hình  
tổ tiên của nó  
Hình hai chiều  
Hình ba chiều  
Hình lăng trụ  
Hình tròn  
Tứ giác  
Tam giác  
Hình cầu  
Tứ diện  
33  
34  
Lớp Object  
Lớp Object (2)  
n Trong gói java.lang  
n Chứa một số phương thức hữu ích kế thừa lại  
cho tất cả các lớp, ví dụ: toString(),  
equals()...  
n Nếu một lớp không được định nghĩa là lớp  
con của một lớp khác thì mặc định nó là lớp  
con trực tiếp của lớp Object.  
à Lớp Object là lớp gốc trên cùng của tất cả  
các cây phân cấp kế thừa  
35  
9
9/18/17  
3.2. Nguyên lý kế thừa  
3.2. Nguyên lý kế thừa (2)  
n Chỉ định truy cập protected  
n Thành viên protected trong lớp cha được truy cập  
public  
protected private  
Không có  
trong:  
n
n
n
Các thành viên lớp cha  
Các thành viên lớp con  
Các thành viên các lớp cùng thuộc 1 package với lớp cha  
Cùng lớp  
cha  
n Lớp con có thể kế thừa được gì?  
Lớp con  
cùng gói  
n
Kế thừa được các thành viên được khai báo là public và  
protected của lớp cha.  
n
n
Không kế thừa được các thành viên private.  
Các thành viên có chỉ định truy cập mặc định nếu lớp cha  
cùng gói với lớp con  
Lớp con  
khác gói  
Khác gói,  
non-inher  
37  
38  
3.2. Nguyên lý kế thừa (2)  
3.2. Nguyên lý kế thừa (3)  
n Các trường hợp không được phép kế thừa:  
public  
Yes  
protected private  
Không có  
Yes  
n
Các phương thức khởi tạo và hủy  
n
Làm nhiệm vụ khởi đầu và gỡ bỏ các đối tượng  
Cùng lớp  
cha  
Yes  
Yes  
Yes  
No  
Yes  
No  
No  
No  
n
Chúng chỉ biết cách làm việc với từng lớp cụ thể  
n
Toán tử gán =  
Lớp con  
cùng gói  
Yes  
Yes  
n
Làm nhiệm vụ giống như phương thức khởi tạo  
Lớp con  
khác gói  
Yes  
No  
Khác gói,  
non-inher  
Yes  
No  
39  
40  
10  
9/18/17  
public class TuGiac {  
protected Diem d1, d2, d3, d4;  
public void setD1(Diem _d1) {d1=_d1;}  
public Diem getD1(){return d1;}  
3.3. Cú pháp kế thừa trên Java  
Ví dụ 1.1  
public void printTuGiac(){...}  
…
n Cú pháp kế thừa trên Java:  
Sử dụng các thuộc tính  
protected của lớp cha  
trong lớp con  
}
n
<Lớp con> extends <Lớp cha>  
n Lớp cha nếu được định nghĩa là finalthì không  
thể có lớp dẫn xuất từ nó.  
public class HinhVuong extends TuGiac {  
public HinhVuong(){  
d1 = new Diem(0,0); d2 = new Diem(0,1);  
d3 = new Diem(1,0); d4 = new Diem(1,1);  
}
n Ví dụ:  
class HinhVuong extends TuGiac {  
}
public class Test{  
...  
}
public static void main(String args[]){  
HinhVuong hv = new HinhVuong();  
hv.printTuGiac();  
Gọi phương thức public  
}
lớp cha của đối tượng lớp con  
41  
42  
}
public class TuGiac {  
protected Diem d1, d2, d3, d4;  
public void printTuGiac(){...}  
public TuGiac(){...}  
public TuGiac(Diem d1, Diem d2,  
Ví dụ 2  
protected  
Ví dụ 1.2  
class Person {  
private String name;  
private Date birthday;  
Diem d3, Diem d4) { ...}  
}
public String getName() {return name;}  
...  
public class HinhVuong extends TuGiac {  
public HinhVuong(){ super(); }  
public HinhVuong(Diem d1, Diem d2,  
}
class Employee extends Person {  
private double salary;  
public boolean setSalary(double sal){  
salary = sal;  
Diem d3, Diem d4){  
super(d1, d2, d3, d4);  
}
}
return true;  
public class Test{  
}
public static void main(String args[]){  
public String getDetail(){  
String s = name+", "+birthday+", "+salary;  
}
HinhVuong hv = new HinhVuong();  
hv.printTuGiac();  
//Loi  
}
}
43  
44  
}
11  
9/18/17  
Ví dụ 2  
Ví dụ 2 (tiếp)  
protected  
class Person {  
public class Test {  
protected String name;  
protected Date bithday;  
public String getName() {return name;}  
...  
public static void main(String args[]){  
Employee e = new Employee();  
e.setName("John");  
e.setSalary(3.0);  
}
}
class Employee extends Person {  
}
private double salary;  
public boolean setSalary(double sal){  
salary = sal;  
return true;  
}
public String getDetail(){  
String s = name+", "+birthday+", "+salary;  
}
}
45  
46  
Ví dụ 3 – Cùng gói  
Ví dụ 3 – Khác gói  
package abc;  
public class Person {  
public class Person {  
Date birthday;  
String name;  
...  
protected Date birthday;  
protected String name;  
...  
}
}
public class Employee extends Person {  
...  
import abc.Person;  
public class Employee extends Person {  
public String getDetail() {  
String s;  
String s = name + "," + birthday;  
...  
public String getDetail() {  
s += ", " + salary;  
String s;  
return s;  
s = name + "," + birthday + "," + salary;  
return s;  
}
}
}
}
47  
48  
12  
9/18/17  
3.4.1. Tự động gọi constructor của lớp  
cha  
3.4. Khởi tạo và huỷ bỏ đối tượng  
public class TuGiac {  
protected Diem d1, d2;  
protected Diem d3, d4;  
public TuGiac(){  
System.out.println  
("Lop cha TuGiac()");  
}
public class Test {  
n Khởi tạo đối tượng:  
public static void  
main(String arg[])  
{
n
Lớp cha được khởi tạo trước lớp con.  
n
Các phương thức khởi tạo của lớp con luôn gọi  
phương thức khởi tạo của lớp cha ở câu lệnh đầu  
tiên  
HinhVuong hv =  
new HinhVuong();  
//…  
}
}
}
n
Tự động gọi (không tường minh - implicit): Khi lớp cha  
CÓ phương thức khởi tạo mặc định  
public class HinhVuong  
extends TuGiac {  
public HinhVuong(){  
//Tu dong goi TuGiac()  
System.out.println  
("Lop con HinhVuong()");  
}
n
Gọi trực tiếp (tường minh - explicit)  
n Hủy bỏ đối tượng:  
n
Ngược lại so với khởi tạo đối tượng  
49  
50  
}
3.4.2. Gọi trực tiếp constructor của lớp  
cha  
Ví dụ  
public class Test {  
public static  
void main(String  
arg[])  
public class TuGiac {  
protected Diem d1, d2;  
protected Diem d3, d4;  
public TuGiac(Diem d1,  
Diem d2, Diem d3, Diem d4){  
System.out.println("Lop cha  
TuGiac(d1, d2, d3, d4)");  
this.d1 = d1; this.d2 = d2;  
this.d3 = d3; this.d4 = d4;  
}
n Câu lệnh đầu tiên trong phương thức khởi tạ  
o của lớp con có thể gọi phương thức khởi tạ  
o của lớp cha  
{
HinhVuong hv =  
new  
n
super(Danh_sach_tham_so);  
HinhVuong();  
}
}
n
Điều này là bắt buộc nếu lớp cha không có  
phương thức khởi tạo mặc định  
Lỗi  
n
Đã viết phương thức khởi tạo của lớp cha với một số  
tham số  
}
public class HinhVuong extends
n
Phương thức khởi tạo của lớp con không bắt buộc phải  
có tham số.  
public HinhVuong(){  
System.out.println  
("Lop con HinhVuong()");  
51  
}
}
13  
9/18/17  
Gọi trực tiếp constructor của lớp cha  
Phương thức khởi tạo lớp con CÓ tham số  
Gọi trực tiếp constructor của lớp cha  
Phương thức khởi tạo lớp con KHÔNG tham số  
public class TuGiac {  
public class TuGiac {  
. . .  
HinhVuong hv = new  
. . .  
protected Diem d1,d2,d3,d4;  
public TuGiac(Diem d1, Diem d2,  
Diem d3, Diem d4){  
protected Diem d1,d2,d3,d4;  
public TuGiac(Diem d1,  
Diem d2, Diem d3, Diem d4){  
System.out.println  
("Lop cha TuGiac(d1,d2,d3,d4)");  
this.d1 = d1; this.d2 = d2;  
this.d3 = d3; this.d4 = d4;  
HinhVuong hv =  
new HinhVuong(  
new Diem(0,0),  
new Diem(0,1),  
HinhVuong();  
System.out.println("Lop cha  
TuGiac(d1, d2, d3, d4)");  
this.d1 = d1; this.d2 = d2;  
this.d3 = d3; this.d4 = d4;  
}
new Diem(1,1),  
new Diem(1,0));  
}
}
}
public class HinhVuong extends TuGiac {  
public class HinhVuong extends TuGiac {  
public HinhVuong(Diem d1, Diem d2,  
public HinhVuong(){  
super(new Diem(0,0), new Diem(0,1),  
new Diem(1,1),new Diem(1,0));  
System.out.println("Lop con HinhVuong()");  
Diem d3, Diem d4){  
super(d1, d2, d3, d4);  
System.out.println("Lop con HinhVuong(d1,d2,d3,d4)");  
}
}
}
}
53  
54  
public class TG {  
private String name;  
public TG(String name) {  
}
}
public class HV extends TG{  
public void test(){  
}
}
55  
14  
pdf 14 trang yennguyen 22300 Free
Bạn đang xem tài liệu "Bài giảng Lập trình hướng đối tượng - Bài 5: Kết tập và kế thừa", để tải tài liệu gốc về máy hãy click vào nút Download ở trên

File đính kèm:

  • pdfbai_giang_lap_trinh_huong_doi_tuong_bai_5_ket_tap_va_ke_thua.pdf