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
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:
bai_giang_lap_trinh_huong_doi_tuong_bai_5_ket_tap_va_ke_thua.pdf

