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

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 Lập trình cấu trúc: Tái sử dụng

hàm/chương trình con

n 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 à Làm thế nào để tái sử dụng

lớp đã viết?

Tái sử dụng mã nguồn (2)

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)

n Tạo ra lớp mới trên cơ sở phát triển từ lớp cũ đã

có à Kế thừa (Inheritance)

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

Trang 1

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

Trang 2

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

Trang 3

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

Trang 4

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

Trang 5

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

Trang 6

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

Trang 7

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

Trang 8

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

Trang 9

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

Trang 10

Tải về để xem bản đầy đủ

pdf 14 trang duykhanh 5440
Bạn đang xem 10 trang mẫu của tài liệu "Bài giảng Lập trình hướng đối tượng - Chương 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

Tóm tắt nội dung tài liệu: Bài giảng Lập trình hướng đối tượng - Chương 5: Kết tập và kế thừa

Bài giảng Lập trình hướng đối tượng - Chương 5: Kết tập và kế thừa
)
n Nâng cao khả năng mô hình 
 hóa thế giới thực 3. Kế thừa (Inheritance)
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ụ: n Kết tập (aggregation)
 n Điểm n Tạo ra các đối tượng của các lớp có sẵn trong 
 n Tứ giác gồm 4 điểm lớp mới à thành viên của lớp mới.
 à 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 n Lớp mới
 n Quan hệ chứa/có ("has- n Lớp toàn thể (Aggregate/Whole), 
 a") hoặc là một phần 
 n Lớp cũ 
 (is-a-part-of)
 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 Lớp toàn thể chứa đối tượng n Sử dụng "hình thoi" tại đầu của 
 của lớp thành phần lớp toàn thể
 n Sử dụng bội số quan hệ 
 n Là một phần (is-a-part of) của (multiplicity) tại 2 đầu
 lớp toàn thể n 1 số nguyên dương: 1, 2,...
 n Tái sử dụng các thành phần dữ n Dải số (0..1, 2..4)
 liệu và các hành vi của lớp thành n *: Bất kỳ số nào
 phần thông qua đối tượng thành n Không có: Mặc định là 1
 phần 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
 private Diem d1, d2; TuGiac Diem public class Test {
 private Diem d3, d4; public static void main(String arg[])
 public TuGiac(Diem p1, Diem p2, {
 Diem p3, Diem p4){ Diem d1 = new Diem(2,3);
 d1 = p1; d2 = p2; d3 = p3; d4 = p4; Diem d2 = new Diem(4,1);
 } Diem d3 = new Diem (5,1);
 public TuGiac(){ Diem d4 = new Diem (8,4);
 d1 = new Diem(); d2 = new Diem(0,1);
 d3 = new Diem (1,1); d4 = new Diem (1,0); TuGiac tg1 = new TuGiac(d1, d2, d3, d4);
 } TuGiac tg2 = new TuGiac();
 public void printTuGiac(){ tg1.printTuGiac();
 d1.printDiem(); d2.printDiem(); tg2.printTuGiac();
 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]; và 1 trọng tài.
 public TuGiac(Diem p1, Diem p2, 
 Diem p3, Diem p4){ n Cần 4 lớp:
 diem[0] = p1; diem[1] = p2; 
 n Người chơi (Player)
 diem[2] = p3; diem[3] = p4;
 } n Súc sắc (Die)
 public void printTuGiac(){ n Trọng tài (Arbitrator)
 diem[0].printDiem(); diem[1].printDiem(); n Trò chơi (Game)
 diem[2].printDiem(); diem[3].printDiem(); à Lớp Trò chơi là lớp kết tập của 3 lớp còn lại
 System.out.println();
 }
} 17 18
 Game Die 2.4. Thứ tự khởi tạo trong kết tập
 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 
 Player và gán những giá trị tương ứng.
 Arbitrator - name : String
 2
- name : String - points : int n Các đối tượng thành phần được khởi tạo 
+ countingPoints() + throwDie() trước
 class Game à Các phương thức khởi tạo của các lớp của 
 {
 Die die1, die2, die3; các đối tượng thành phần được thực hiện 
 Player player1, player2; trước
 Arbitrator arbitrator1;
 ...
 } 19 20
 5
 9/18/17
Bài tập: public class PhongBan {
 private String tenPhongBan; private byte soNhanVien;
n Viết mã nguồn cho lớp PhongBan vớ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 public static final SO_NV_MAX = 100;
 với số lượng tham số cần thiết, biết rằng: private NhanVien[] dsnv;
 public boolean themNhanVien(NhanVien nv){
 n Việc thêm/xóa nhân viên được thực hiện theo cơ chế của 
 stack if (soNhanVien < SO_NV_MAX) { 
 n tongLuong() trả về tổng lương của các nhân viên trong dsnv[soNhanVien] = nv; soNhanVien++;
 phòng. return true;
 n inTTin() hiển thị thông tin của phòng và thông tin của các } else return false;
 nhân viên trong phòng. }
 PhongBan NhanVien public NhanVien xoaNhanVien(){
 1 1..*
-tenPhongBan:String -tenNhanVien:String if (soNhanVien > 0) {
 -heSoLuong:double
-soNhanVien:byte NhanVien tmp = dsnv[soNhanVien-1];
 +LUONG_CO_BAN:double=750.000
+SO_NV_MAX:byte = 100 dsnv[soNhanVien-1] = null; soNhanVien--; 
 +LUONG_MAX:double=20.000.000
+themNV(NhanVien):boolean return tmp;
+xoaNV():NhanVien +tangLuong(double):boolean } else return null;
+tongLuong():double +tinhLuong():double }
 21 22
+inTTin() +inTTin() // (cont)...
 // (cont.)
 public PhongBan(String tenPB){ Thảo luận
 dsnv = new NhanVien[SO_NV_MAX];
 tenPhongBan = tenPB; soNhanVien = 0;
 } Trong ví dụ trên 
 public double tongLuong(){
 double tong = 0.0; n Lớp cũ? Lớp mới?
 for (int i=0;i<soNhanVien;i++)
 n Lớp cũ: NhanVien
 tong += dsnv[i].tinhLuong();
 return tong; n Lớp mới: PhongBan
 }
 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); n Mảng đối tượng của lớp NhanVien: dsnv
 System.out.println("So NV: "+soNhanVien);
 n Lớp mới tái sử dụng được những gì của lớp 
 System.out.println("Thong tin cac NV");
 for (int i=0;i<soNhanVien;i++) cũ?
 dsnv[i].inTTin();
 n tinhLuong() trong phương thức tongLuong()
 }
 23 24
} n inTTin() trong phương thức inTTin()
 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
 n Tứ giác gồm 4 điểm 
 2. Kết tập (Aggregation) à Kết tập
 3. Kế thừa (Inheritance) n Tứ giác
 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 
 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. dữ liệu và các hành vi của lớp cha
 n Chi tiết hóa cho phù hợp với mục đích sử dụng 
n Lớp cũ:
 mới
 n Lớp cha (parent, superclass), lớp cơ sở (base 
 n Extension: Thêm các thuộc tính/hành vi mới
 class)
 n Redefinition (Method Overriding): Chỉnh sửa lại các 
n Lớp mới: hành vi kế thừa từ lớp cha
 n Lớp con (child, subclass), lớp dẫn xuất (derived 
 class)
 27 28
 7
 9/18/17
 3.1.2. Biểu diễn kế thừa trong UML 3.1.3. Kết tập và kế thừa
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
 Hinh Hinh Whale Horse
 Vuong Thang
 29 30
 3.1.4. Cây phân cấp kế thừa 
 Phân biệt kế thừa và kết tập (Inheritance hierarchy)
 Kế thừa Kết tập A
n Kế thừa tái sử dụng n Kết tập tái sử dụng thông n Cấu trúc phân cấp hình cây, biểu diễn mối 
 thông qua lớp. qua đối tượng. quan hệ kế thừa giữa các lớp. B
 n Tạo lớp mới bằng cách 
 n Tạo ra lớp mới là tập hợp 
 phát triển lớp đã có n Dẫn xuất trực tiếp
 các đối tượng của các lớp 
 n B dẫn xuất trực tiếp từ A 
 n Lớp con kế thừa dữ đã có Vehicle C
 n Dẫn xuất gián tiếp
 liệu và hành vi của lớp n Lớp toàn thể có thể sử 
 cha dụng dữ liệu và hành vi n C dẫn xuất gián tiếp từ A
 thông qua các đối tượng 
 Car Moto
n Quan hệ "là một loại" thành phần
 ("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 n Ví dụ: Bánh xe là một SportCar Compact SportMoto
 phần của Ô tô 31 32
 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ừ 
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 lớp gốc Object
 tổ tiên của nó Hình
 Hình hai chiều Hình ba chiều
 Hình tròn Tứ giác Tam giác Hình cầu Hình lăng trụ 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 
n Nếu một lớp không được định nghĩa là lớp cho tất cả các lớp, ví dụ: toString(), 
 con của một lớp khác thì mặc định nó là lớp equals()...
 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 36
 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 Không có protected private
 trong:
 n Các thành viên lớp cha
 n Các thành viên lớp con Cùng lớp 
 n Các thành viên các lớp cùng thuộc 1 package với lớp cha cha
n Lớp con có thể kế thừa được gì? Lớp con 
 n Kế thừa được các thành viên được khai báo là public và 
 protected của lớp cha. cùng gói
 n Không kế thừa được các thành viên private. Lớp con 
 n 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 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 Không có protected private 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 Yes Yes Yes Yes n Chúng chỉ biết cách làm việc với từng lớp cụ thể
 cha n Toán tử gán =
 Lớp con Yes Yes Yes No n Làm nhiệm vụ giống như phương thức khởi tạo
 cùng gói
 Lớp con Yes No Yes No
 khác gói
 Khác gói, Yes No No No
 non-inher 39 40
 10
 9/18/17
 public class TuGiac {
 3.3. Cú pháp kế thừa trên Java protected Diem d1, d2, d3, d4;
 public void setD1(Diem _d1) {d1=_d1;} 
 public Diem getD1(){return d1;}
 public void printTuGiac(){...} Ví dụ 1.1
n Cú pháp kế thừa trên Java: 
  Sử dụng các thuộc tính 
 n extends } protected của lớp cha 
 trong lớp con
n Lớp cha nếu được định nghĩa là final thì không public class HinhVuong extends TuGiac {
 thể có lớp dẫn xuất từ nó. public HinhVuong(){
 d1 = new Diem(0,0); d2 = new Diem(0,1);
n Ví dụ: d3 = new Diem(1,0); d4 = new Diem(1,1);
 }
 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; Ví dụ 2
 public void printTuGiac(){...} Ví dụ 1.2 protected
 public TuGiac(){...}
 public TuGiac(Diem d1, Diem d2, class Person {
 Diem d3, Diem d4) { ...} private String name;
 } private Date birthday;
 public class HinhVuong extends TuGiac { public String getName() {return name;}
 public HinhVuong(){ super(); } ...
 public HinhVuong(Diem d1, Diem d2, }
 Diem d3, Diem d4){ class Employee extends Person {
 super(d1, d2, d3, d4); private double salary;
 } public boolean setSalary(double sal){
 } salary = sal;
 public class Test{ return true;
 public static void main(String args[]){ }
 HinhVuong hv = new HinhVuong(); public String getDetail(){
 hv.printTuGiac(); String s = name+", "+birthday+", "+salary; //Loi
 } }
 43 44
 } }
 11
 9/18/17
 Ví dụ 2 Ví dụ 2 (tiếp)
 protected
class Person { public class Test {
 protected String name; public static void main(String args[]){ 
 protected Date bithday; Employee e = new Employee();
 public String getName() {return name;} 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
public class Person { package abc;
 Date birthday; public class Person {
 String name; protected Date birthday;
 ... protected String name;
} ...
 }
public class Employee extends Person {
 ...
 import abc.Person;
 public String getDetail() { public class Employee extends Person {
 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 
 3.4. Khởi tạo và huỷ bỏ đối tượng cha
 public class TuGiac {
n Khởi tạo đối tượng: protected Diem d1, d2; public class Test {
 protected Diem d3, d4; public static void 
 n Lớp cha được khởi tạo trước lớp con. public TuGiac(){ main(String arg[])
 n Các phương thức khởi tạo của lớp con luôn gọi System.out.println {
 phương thức khởi tạo của lớp cha ở câu lệnh đầu ("Lop cha TuGiac()"); HinhVuong hv = 
 } new HinhVuong();
 tiên // }
 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 {
 n Gọi trực tiếp (tường minh - explicit)
 public HinhVuong(){
n Hủy bỏ đối tượng: //Tu dong goi TuGiac()
 System.out.println
 n Ngược lại so với khởi tạo đối tượng ("Lop con HinhVuong()");
 49 } 50
 }
 3.4.2. Gọi trực tiếp constructor của lớp 
 cha Ví dụ
 public class Test {
 public static 
 public class TuGiac { void main(String 
n Câu lệnh đầu tiên trong phương thức khởi tạ protected Diem d1, d2; arg[])
 o của lớp con có thể gọi phương thức khởi tạ protected Diem d3, d4; {
 public TuGiac(Diem d1, 
 o của lớp cha HinhVuong hv = 
 Diem d2, Diem d3, Diem d4){ new 
 System.out.println("Lop cha 
 n super(Danh_sach_tham_so);
 TuGiac(d1, d2, d3, d4)"); HinhVuong();
 n Điều này là bắt buộc nếu lớp cha không có 
 this.d1 = d1; this.d2 = d2; }
 this.d3 = d3; this.d4 = d4;
 phương thức khởi tạo mặc định }
 }
 n Đã viết phương thức khởi tạo của lớp cha với một số Lỗi
 }
 tham số public class HinhVuong extends TuGiac {
 n Phương thức khởi tạo của lớp con không bắt buộc phải public HinhVuong(){
 có tham số. System.out.println
 ("Lop con HinhVuong()");
 51 } 52
 }
 13
 9/18/17
 Gọi trực tiếp constructor của lớp cha 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ố Phương thức khởi tạo lớp con CÓ tham số
public class TuGiac { public class TuGiac {
 protected Diem d1,d2,d3,d4; . . . protected Diem d1,d2,d3,d4; . . .
 HinhVuong hv = new 
public TuGiac(Diem d1, Diem d2, public TuGiac(Diem d1, HinhVuong hv = 
 Diem d3, Diem d4){ HinhVuong(); Diem d2, Diem d3, Diem d4){ new HinhVuong(
 System.out.println("Lop cha System.out.println new Diem(0,0), 
 TuGiac(d1, d2, d3, d4)"); ("Lop cha TuGiac(d1,d2,d3,d4)"); new Diem(0,1), 
 this.d1 = d1; this.d2 = d2; this.d1 = d1; this.d2 = d2; new Diem(1,1), 
 this.d3 = d3; this.d4 = d4; this.d3 = d3; this.d4 = d4; new Diem(1,0));
 } }
} }
public class HinhVuong extends TuGiac { public class HinhVuong extends TuGiac {
 public HinhVuong(){ public HinhVuong(Diem d1, Diem d2, 
 super(new Diem(0,0), new Diem(0,1), Diem d3, Diem d4){
 new Diem(1,1),new Diem(1,0)); super(d1, d2, d3, d4);
 System.out.println("Lop con HinhVuong()"); 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

File đính kèm:

  • pdfbai_giang_lap_trinh_huong_doi_tuong_chuong_5_ket_tap_va_ke_t.pdf