Bài giảng Lập trình hướng đối tượng Chương 5 Thừa kế cung cấp cho người học các kiến thức Vấn đề tái sử dụng code các hình thức, lý do thừa kế, lớp cơ sở, lớp dẫn xuất, sử dụng lớp cơ sở, constructor và thừa kế,... Mời các bạn cùng tham khảo nội dung chi tiết.
Trang 1Click to edit Master subtitle style
THỪA KẾ
Khoa Công nghệ thông tin Trường Đại học Ngoại ngữ - Tin học, TP.HCM
CHƯƠNG 5:
Trang 2Vấn đề tái sử dụng code & các hình thức
Access modifier: protected
Lớp cơ sở của mọi lớp: Lớp object
Lớp sealed và lớp partial
NỘI DUNG
2
Trang 3Xuất phát từ nhu cầu:
Sử dụng lại những đoạn code có sẵn Hoặ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óa
Vấn đề tái sử dụng code
Trang 4Lập trình cấu trúc: chương trình con
OOP: nhiều loại đối tượng có thuộc tính, hành
Trong một lớp vẫn tái sử dụng phương thức
Vấn đề tái sử dụng code
4
Trang 5Có 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 đổi
Kết tập (Aggregation): Lớp mới là tập hợp hoặ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 code
Trang 6KẾT TẬP (AGGREGATION)
6
Trang 7Thà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ượng
Lớp cũ: Lớp thành phần
Ví dụ:
Lớp cũ: Điểm (Point) Lớp mới: Tam giác (Triangle) có 3 điểm
Kết tập (Aggregation)
Trang 8Số 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à 1
Ký hiệu quan hệ kết tập
8
Trang 9}
Trang 10Cài đặt lớp Point và lớp Triangle có chức năng:
Nhập Xuất Tính chu vi Tí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ất
Bài tập tại lớp
10
Trang 11Xâ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 6
Quy định số lần gieo xúc xắc
Hai người lần lượt gieo 1 hạt xúc xắc
Sau 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 ứng
Sau 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ơn
Bài tập ví dụ
Trang 12Xú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ớp
12
Trang 13Trậ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ớp
Trang 14Sơ đồ lớp
14
Trang 15public class XucXac
private 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);
}
Trang 16public class NguoiChoi
private String ten;
private int diem;
//Định nghĩa constructor, property get, set
Console Write( " - Diem hien tai = " + this diem); }
Trang 17public class TranDau
private 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 <= this soVong; i++)
{
Console WriteLine("***** Vong {0} *****", i);
Console WriteLine(nguoiChoi1.Ten+" gieo xuc xac");
Trang 18public class TranDau
public void KetThuc()
{
int diem1 = nguoiChoi1.Diem;
int diem2 = nguoiChoi2.Diem;
if (diem1 > diem2)
this nguoiThang = this nguoiChoi1;
else if (diem2 > diem1)
this nguoiThang = this nguoiChoi2;
}
Trang 19public class TranDau
public void HienThi()
{
Console WriteLine("*** Ket qua tran dau ***");
Console WriteLine("- Diem cua {0}: {1}", nguoiChoi1.Ten,
Trang 20Hã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ắng Cho 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 đấu
Nếu hòa thì tính điểm để kết luận người thắng
Bài tập về nhà
20
Trang 21THỪA KẾ
Trang 22Đó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)
3 nguyên tắc lập trình hướng đối tượng
22
Trang 23Tạ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)
Trang 24Kế thừa
24
Trang 25Ký hiệu kế thừa
Trang 26Lớp Student thừa kế Person
Lớp Student tái sử dụng mọi thứ của lớp Person
Mọi thay đổi của lớp Person sẽ tự động thay đổi trong lớp
Student
Ví dụ
26
Trang 27Ví dụ: Tam giác vuông là một
loại tam giác
Ví dụ: Tam giác có 3 đỉnh
Trang 28Đơn kế thừa (single inheritance): chỉ có một lớp cha
Đa kế thừa (multiple inheritance): có nhiều lớp cha
Các dạng kế thừa
28
Trang 30LỚP CƠ SỞ
30
Trang 31Lớp cơ sở (base class, superclass, parent class)
cho lớp khác thừa kế
Lớp cơ sở
class Person
{
public string Email { get; set; }
public string Name { get; set; }
Trang 32LỚP DẪN XUẤT
32
Trang 33Lớ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ác
Lớp dẫn xuất
Lớp Student dẫn xuất từ lớp Person Lớp Student thừa kế từ lớp Person
Trang 34Tạo lớp dẫn xuất
Lớp dẫn xuất
class Student : Person
{ //
} class Student : Person
{ public string StudentID { get; set; }
public Student(string studentID) {
StudentID = studentID;
Name = "NA";
Email = "NA";
} }
34
Trang 36SỬ DỤNG LỚP DẪN XUẤT
36
Trang 37Cách 1: Sử dụng như bất kỳ lớp nào khác
Person
Biến person là một student có mã 15TH123456 Nhưng person chỉ được dùng những thứ có trong person
Sử dụng lớp dẫn xuất
Person person = new Person(“Khánh Phương”);
Student student = new Student(“15TH123456”);
Person person = new Student(“15TH123456”);
Trang 38Ví dụ:
int x = 20.5; //error?
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ự động
Downcasting: đố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ểu
Kiểm tra kiểu và ép kiểu (casting)
38
Trang 39person là một Student có mã 15TH123456
nhưng lại dùng như Person
Kiể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 }
Trang 40Thay 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;
40
Trang 42So sánh casting và as
Từ khóa ‘ as ’
Person person = new Teacher();
Student = (Student) person;
Person person = new Teacher();
Student = person as Student;
Trang 43Mộ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ảng
Person [] people = new Person [5];
people[3] = new Student(“15TH123456”);
people[4] = new Teacher();
Trang 44CONSTRUCTOR VÀ THỪA KẾ
44
Trang 45Lớp dẫn xuất sẽ thừa kế
Fields Methods, Properties, Indexers, Events
Không thể dùng constructor của lớp cơ sở để tạo lớp dẫn xuất
Chúng ta phải tự tạo constructor của lớp dẫn xuất
Constructor trong thừa kế
Trang 46Khi 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ở
constructor không tham số của lớp cơ sở
Constructor trong thừa kế
46
Trang 47Tì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ố)
Constructor trong thừa kế
Trang 48Constructor trong thừa kế
{ StudentID = studentID }
// … }
48
Trang 49ACCESS MODIFIER: PROTECTED
Trang 50Đã học, thành viên lớp:
private public
Khi thừa kế, chúng ta có thêm
Trang 51LỚP OBJECT
Trang 52Bất kỳ lớp nào chúng ta tạo ra đều dẫn xuất từ
Lớp object: Lớp cơ sở của mọi lớp (trực tiếp
hay gián tiếp)
Lớp object
object student = new Student(“15TH123456”);
52
Trang 53Trả về chuỗi biểu diễn (mô tả) đối tượng
double x, y;
… public override ToString() {
return “(” + x + “,” + y + “)”;
} }
Trang 54LỚP SEALED VÀ LỚP PARTIAL
54
Trang 55Có lúc cần ngăn cản một lớp cho thừa kế
Trang 56Đôi lúc một lớp trở nên lớn
Chia lớp thành các lớp nhỏ hơn Chia lớp thành nhiều file hay nhiều section (dùng
public partial class Something
{
public void DoSomethingElse {
} }
56
Trang 57Thiết kế các lớp cần thiết (áp dụng kỹ thuật kế
sinh viên
Đối với sinh viên gồm các thông tin và hành vi:
Họ tên Tuổi Tên trường học
Số tín chỉ đã tích luỹ Cập nhật số tín chỉ Hiển thị thông tin
Bài tập
Trang 58Đối với giảng viên gồm các thông tin và hành vi:
Họ tên Tuổi Tên trường công tác Học vị
Hệ số lương Mức lương cơ bản Hiển thị thông tin
Bài tập …
58
Trang 59Thừ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)
Fields
Methods, Properties, …
Thừa kế: class Something : Another {…}
dẫn xuất cũng có thể truy cập
ĐIỂM CHÍNH