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