Lập trình hướng đối tượng - Chương 5: Thừa kế
Tình huống:
Nếu lớp cơ sở Không có constructor không tham số
Constructor của lớp dẫn xuất muốn gọi constructor khác (không phải constructor không tham số)
Giải pháp: Dùng từ khóa “base”
59 trang |
Chia sẻ: huyhoang44 | Lượt xem: 723 | Lượt tải: 0
Bạn đang xem trước 20 trang tài liệu Lập trình hướng đối tượng - Chương 5: Thừa kế, để xem tài liệu hoàn chỉnh bạn click vào nút DOWNLOAD ở trên
THỪA KẾKhoa Công nghệ thông tinTrường Đại học Ngoại ngữ - Tin học, TP.HCMCHƯƠNG 5: 1Vấn đề tái sử dụng code & các hình thứcLý do thừa kếLớp cơ sởLớp dẫn xuấtSử dụng lớp cơ sởConstructor và thừa kếAccess modifier: protectedLớp cơ sở của mọi lớp: Lớp objectLớp sealed và lớp partial NỘI DUNG2Xuất phát từ nhu cầu: Sử dụng lại những đoạn code có sẵnHoặc phát triển thêm từ những code có sẵn mà không phải viết lại từ đầu Ưu điểm:Giảm chi phíNâng cao khả năng bảo trì và khả năng mô hình hóaVấn đề tái sử dụng code3Lập trình cấu trúc: chương trình conOOP: 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ếtTrong một lớp vẫn tái sử dụng phương thứcVấn đề tái sử dụng code4Có 3 hình thức: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 đổiKết tập (Aggregation): Lớp mới là tập hợp hoặc sử dụng (không thay đổi) các lớp đã cóThừa kế (Inheritance): 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óCác hình thức tái sử dụng code5KẾT TẬP (aggregation)6Thành phần lớp mới chứa các đối tượng của lớp cũLớp mới: Lớp chứa/Lớp toàn thể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ượngLớp cũ: Lớp thành phầnVí dụ:Lớp cũ: Điểm (Point)Lớp mới: Tam giác (Triangle) có 3 điểmKết tập (Aggregation)7Số lượng lớp thành phần trong lớp chứa có thể: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à 1Ký hiệu quan hệ kết tập8Ví dụ quan hệ kết tập9public class Point{ private int x; private int y; //Định nghĩa các phương thức}public class Triangle{ Point dinhA; //Đỉnh A Point dinhB; //Đỉnh B Point dinhC; //Đỉnh C //Định nghĩa các phương thức}Cài đặt lớp Point và lớp Triangle có chức năng:NhậpXuấtTính chu viTính diện tích(Mỗi lớp phải có: Property get, set; constructor; kiểm tra ràng buộc nếu có)Cài đặt lớp ListTriangle chứa danh sách các Triangle có chức năng: nhập, xuất và cho biết thông tin tam giác có diện tích lớn nhấtBài tập tại lớp10Xây dựng chương trình trò chơi xúc xắc với cách chơi như sau:Mỗi xúc xắc sẽ có giá trị ngẫu nhiên từ 1 đến 6Quy định số lần gieo xúc xắcHai người lần lượt gieo 1 hạt xúc xắcSau 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 tương ứngSau 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ơnBài tập ví dụ11Xúc xắc (XucXac)Thuộc tính: giá trị của mặt (giaTri)Phương thức: sinh ngẫu nhiên giá trị mặt của xúc xắc (SinhGiaTri())Người chơi (NguoiChoi)Thuộc tính: tên (ten), điểm (diem)Phương thức: gieo xúc xắc (GieoXucXac())Phát hiện lớp và thông tin của lớp12Trận đấu (TranDau)Thuộc tính: xúc xắc (xucXac), 2 người chơi (nguoiChoi), số vòng chơi (soVong), người thắng cuộc (nguoiThang)Phương thức: bắt đầu (BatDau()), kết thúc (KetThuc), hiển thị thông tin (HienThi()), thực hiện trận đấu (ThucHienTranDau())Phát hiện lớp và thông tin của lớp13Sơ đồ lớp14public class XucXacprivate int giaTri; //Định nghĩa Constructor và Property get, set //tại đây public void SinhGiaTri(){ Random random = new Random(); this.giaTri = random.Next(1, 7);}public class NguoiChoiprivate String ten;private int diem;//Định nghĩa constructor, property get, set //tại đây ... public void GieoXucXac(XucXac xucXac){ Console.Write("> Nhan Enter "); Console.ReadLine(); xucXac.SinhGiaTri(); this.diem += xucXac.GiaTri; //get giá trị xucXac Console.Write(" - Diem hien tai = " + this.diem);}public class TranDauprivate XucXac xucXac;private NguoiChoi nguoiChoi1;private NguoiChoi nguoiChoi2;private NguoiChoi nguoiThang;private int soVong;//Định nghĩa constructor, property get, set tại đây...public void BatDau(){ Console.WriteLine("Tran dau bat dau..."); for (int i = 1; i diem2) this.nguoiThang = this.nguoiChoi1; else if (diem2 > diem1) this.nguoiThang = this.nguoiChoi2;}public class TranDaupublic void HienThi(){ Console.WriteLine("*** Ket qua tran dau ***"); Console.WriteLine("- Diem cua {0}: {1}", nguoiChoi1.Ten, nguoiChoi1.Diem); Console.WriteLine("- Diem cua {0}: {1}", nguoiChoi2.Ten, nguoiChoi2.Diem); if (nguoiThang != null) Console.WriteLine("Nguoi thang: " + nguoiThang.Ten); else Console.WriteLine("Tran dau hoa!!!");}public void ThucHienTranDau(){ BatDau(); KetThuc(); HienThi();}Hãy viết lại các lớp trong Bài tập ví dụ trên để thoả yêu cầu sau:Có thêm thuộc tính soBanThang ghi lại số bàn thắngCho biết số ván đấu (>2), nếu người chơi nào thắng quá bán đầu tiên thì sẽ thắng VD: 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 đấuNếu hòa thì tính điểm để kết luận người thắngBài tập về nhà20THỪA KẾ21Đóng gói (Encapsulation) và Giao diện (Interface)Ẩn chi tiết của lớp (Đóng gói), chỉ cung cấp các phương thức cần thiết để dùng (Giao diện) Thừa kế (Inheritance)Tạo lớp mới thừa kế lớp đã cóĐa hình (Polymorphism)Khả năng tạo ra các lớp dẫn xuất, cài đặt cùng một method của lớp cơ sở theo những cách khác nhau (tùy từng lớp dẫn xuất)3 nguyên tắc lập trình hướng đối tượng22Tạo lớp mới bằng cách phát triển từ lớp đã cóLớp mới thừa kế những thành viên đã có trong lớp cũLớp cũ: Lớp cha (superclass), lớp cơ sở (baseclass)Lớp mới: Lớp con (subclass), lớp dẫn xuất (derived class)Thừa kế (Inheritance)23Lớp cơ sởLớp tổng quát hơn trong mối quan hệ “is-a”Có cùng tập thuộc tính và hành viLớp dẫn xuấtLớp cụ thể hơn trong một quan hệ “is-a”Có cùng tập thuộc tính và hành vi (do kế thừa từ lớp cơ sở), cộng thêm tập thuộc tính và hành vi của riêng nóKế thừa24Ký hiệu kế thừaLớp Student thừa kế PersonLớp Student tái sử dụng mọi thứ của lớp PersonMọi thay đổi của lớp Person sẽ tự động thay đổi trong lớp StudentVí dụ26Kết tập vs Kế thừaKế thừaKết tậpTái sử dụng mã nguồnthông qua lớpTái sử dụng mã nguồnthông qua đối tượngQuan hệ “là một loại” Quan hệ “là một phần”Ví dụ: Tam giác vuông là một loại tam giácVí dụ: Tam giác có 3 đỉnhĐơn kế thừa (single inheritance): chỉ có một lớp chaĐa kế thừa (multiple inheritance): có nhiều lớp chaCác dạng kế thừa28Nhận biết kế thừa?class Aclass Bclass ABclass Aclass BLỚP CƠ SỞ30Lớp cơ sở (base class, superclass, parent class) là bất kỳ lớp thông thường nào mà được dùng cho lớp khác thừa kế Lớp cơ sởclass Person{ public string Email { get; set; } public string Name { get; set; } public Person() { Email = ""; Name = ""; } public Person(string name) { Name = name; } public Person(string name, string email) { Name = name; Email = email; }}31LỚP DẪN XUẤT32Lớp dẫn xuất (derived class, subclass, child class) là lớp dựa trên hay mở rộng một lớp khácLớp dẫn xuấtLớp Student dẫn xuất từ lớp PersonLớp Student thừa kế từ lớp Person33Tạo lớp dẫn xuấtLớp dẫn xuấtclass Student : Person{ // ...}class Student : Person{ public string StudentID { get; set; } public Student(string studentID) { StudentID = studentID; Name = "NA"; Email = "NA"; }}34Lớp Student cóProperty: StudentIDThừa kế các biến, các properties, các methods của PersonNameEmailChú ý: Một lớp có thể thừa kế từ lớp mà lớp đó lại thừa kế từ lớp khác.Giải thích35Sử dụng lớp dẫn xuất36Cách 1: Sử dụng như bất kỳ lớp nào khácCách 2: Student là một kiểu đặc biệt của Person nên có thể đặt Student vào trong biến kiểu PersonBiến person là một student có mã 15TH123456Nhưng person chỉ được dùng những thứ có trong personSử dụng lớp dẫn xuấtPerson person = new Person(“Khánh Phương”);Student student = new Student(“15TH123456”);Person person = new Student(“15TH123456”);37Ví dụ:int x = 20.5; //error?double y = 10; //OK?Upcasting: đối tượng lớp dẫn xuất được nhìn nhận như đối tượng lớp cơ sở: Thực hiện tự độngDowncasting: đối tượng lớp cơ sở được nhìn nhận như đối tượng lớp dẫn xuất: Phải ép kiểuKiểm tra kiểu và ép kiểu (casting)38person là một Student có mã 15TH123456 nhưng lại dùng như PersonĐể kiểm tra đối tượng có kiểu gì: từ khóa isKiểm tra kiểu và ép kiểu (casting)Person person = new Student(“15TH123456”);Person person = new Student(“15TH123456”);if (person is Student){ Student student = (Student) person; // Làm những gì chúng ta muốn với student}39Thay vì ép kiểu, có một cách khác để chuyển một kiểu đối tượng sang kiểu khác : Dùng từ khóa ‘as’Từ khóa ‘as’Person person = new Student(“15TH123456”);Student student = person as Student;40So sánh casting và as Từ khóa ‘as’class Person {}class Student : Person{}class Teacher : Person{} 41So sánh casting và as Từ khóa ‘as’Person person = new Teacher();Student = (Student) person;Person person = new Teacher();Student = person as Student;if (person != null){ //}42Một thuận lợi là chúng ta có thể tạo một mảng của lớp cơ sở, và đặt bất kỳ lớp dẫn xuất nào vào đóDùng thừa kế trong mảngPerson[] people = new Person[5];people[3] = new Student(“15TH123456”);people[4] = new Teacher();43Constructor và thừa kế44Lớp dẫn xuất sẽ thừa kế FieldsMethods, Properties, Indexers, Events Lớp dẫn xuất không thừa kế constructor Không thể dùng constructor của lớp cơ sở để tạo lớp dẫn xuấtChúng ta phải tự tạo constructor của lớp dẫn xuấtConstructor trong thừa kế45Khi lớp dẫn xuất định nghĩa constructor, nó cần gọi một trong những constructor của lớp cơ sởMặc định, constructor của lớp dẫn xuất gọi constructor không tham số của lớp cơ sởConstructor trong thừa kế46Tình huống:Nếu lớp cơ sở Không có constructor không tham sốConstructor của lớp dẫn xuất muốn gọi constructor khác (không phải constructor không tham số)Giải pháp: Dùng từ khóa “base”Constructor trong thừa kế47Constructor trong thừa kếclass Person{ // public Person() { Email = ""; Name = ""; } public Person(string name) { Name = name; } // }class Student : Person{ // public Student(string studentID) : base(“No name”) { StudentID = studentID } // }48Access modifier: protected49Đã học, thành viên lớp:privatepublicKhi thừa kế, chúng ta có thêm protectedTrong lớp có thể dùngLớp dẫn xuất có thể dùngThành viên protected50Lớp object51Bất kỳ lớp nào chúng ta tạo ra đều dẫn xuất từ một lớp đặc biệt: lớp objectLớp object: Lớp cơ sở của mọi lớp (trực tiếp hay gián tiếp)Có thể dùng lớp object để lưu lớp dẫn xuấtLớp objectobject student = new Student(“15TH123456”);52Trả về chuỗi biểu diễn (mô tả) đối tượngPhương thức ToString()class Student{ public override string ToString() { return Name; } }class Point{ double x, y; public override ToString() { return “(” + x + “,” + y + “)”; } }53Lớp sealed và lớp partial54Có lúc cần ngăn cản một lớp cho thừa kếDùng từ khóa sealedLớp sealedsealed class Student: Person{ }sealed class Something{ }55Đôi lúc một lớp trở nên lớnChia lớp thành các lớp nhỏ hơnChia lớp thành nhiều file hay nhiều section (dùng từ khóa partial)Lớp partialpublic partial class Something{ public void DoSomething { }} public partial class Something{ public void DoSomethingElse { }} 56Thiết kế các lớp cần thiết (áp dụng kỹ thuật kế thừa) để 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:Họ tênTuổiTên trường họcSố tín chỉ đã tích luỹCập nhật số tín chỉHiển thị thông tinBài tập57Đối với giảng viên gồm các thông tin và hành vi:Họ tên TuổiTên trường công tácHọc vịHệ số lươngMức lương cơ bảnHiển thị thông tinBài tập 58Thừa kế là cách tái sử dụng code bằng cách mở rộng lớp cơ sở thành lớp cụ thể (lớp dẫn xuất)Bất kỳ lớp nào cũng có thể làm lớp cơ sở (trừ lớp sealed)Lớp dẫn xuất thừa kế các thành viên của lớp cơ sở (trừ private)FieldsMethods, Properties, Thừa kế: class Something : Another {}protected access modifier: mọi nơi trong lớp có thể truy cập và lớp dẫn xuất cũng có thể truy cập ĐIỂM CHÍNH59
Các file đính kèm theo tài liệu này:
- lap_trinh_huong_doi_tuongchuong_05_thua_ke_7018.pptx