Chúng ta tiếp tục tiến sâu vào lập trình hướng đối tượng. Sau khi bạn đã làm quen với class
và object
, bài học hôm nay sẽ giúp bạn viết mã tái sử dụng thông minh hơn bằng cách kế thừa (inheritance) – một tính năng cực kỳ mạnh mẽ trong lập trình OOP.
Khi con kế thừa tính chất từ cha mẹ
Trong cuộc sống, một học sinh là một con người, một xe tải cũng là một loại xe. Những thực thể này chia sẻ điểm chung, nhưng vẫn có đặc trưng riêng.
Trong lập trình hướng đối tượng, điều này thể hiện qua kế thừa: một lớp mới có thể dùng lại thuộc tính và hành vi từ một lớp cũ, sau đó mở rộng hoặc tùy biến theo nhu cầu.
Mục tiêu bài học
- Biết cách tạo lớp con kế thừa lớp cha
- Hiểu cách dùng
super()
để gọi constructor lớp cha - Ghi đè (
override
) phương thức của lớp cha - Biết phân biệt giữa kế thừa đơn và đa cấp
- Biết khi nào nên sử dụng kế thừa để tái sử dụng code thông minh
1. Lớp cha (Parent) và lớp con (Child)
Ví dụ:
class ConNguoi:
def __init__(self, ten):
self.ten = ten
def chao(self):
print(f"Xin chào, tôi là {self.ten}")
2. Lớp con kế thừa lớp cha
class HocSinh(ConNguoi): # kế thừa ConNguoi
def hoc(self):
print(f"{self.ten} đang học bài.")
hs = HocSinh("An")
hs.chao() # phương thức của lớp cha
hs.hoc() # phương thức riêng của lớp con
Khi
HocSinh
kế thừaConNguoi
, nó có tất cả thuộc tính và phương thức củaConNguoi
, và có thể có thêm hoặc thay đổi.
3. Dùng super()
để gọi constructor lớp cha
class HocSinh(ConNguoi):
def __init__(self, ten, lop):
super().__init__(ten) # gọi __init__ của ConNguoi
self.lop = lop
hs = HocSinh("Bình", "12A1")
hs.chao()
print("Lớp:", hs.lop)
4. Ghi đè phương thức (method override
)
Lớp con có thể viết lại (ghi đè) phương thức lớp cha.
class GiaoVien(ConNguoi):
def chao(self): # ghi đè
print(f"Thầy {self.ten} xin chào các em.")
gv = GiaoVien("Hải")
gv.chao() # Thầy Hải xin chào các em.
5. Kế thừa đa cấp (nhiều lớp chồng lên nhau)
class SinhVien(ConNguoi):
pass
class SinhVienCNTT(SinhVien):
def lap_trinh(self):
print(f"{self.ten} đang viết code Python.")
sv = SinhVienCNTT("Mai")
sv.chao()
sv.lap_trinh()
6. Kiểm tra kế thừa
print(isinstance(sv, SinhVien)) # True
print(isinstance(sv, ConNguoi)) # True
print(issubclass(SinhVienCNTT, ConNguoi)) # True
7. Khi nào nên dùng kế thừa?
- Khi nhiều class có thuộc tính và hành vi giống nhau
- Khi muốn tổ chức chương trình có cấu trúc, dễ mở rộng
- Khi làm việc với nhiều kiểu dữ liệu liên quan
- Khi viết game, phần mềm có nhiều “loại đối tượng” tương tự nhau
8. Bài tập luyện tập
Bài 1: Viết class DongVat
, có phương thức keu()
. Tạo lớp con Cho
, Meo
kế thừa DongVat
, ghi đè keu()
.
Bài 2: Viết class Nguoi
, class SinhVien
kế thừa Nguoi
, thêm thuộc tính ma_sv
, nganh_hoc
.
Bài 3: Viết class HinhHoc
, có phương thức tinh_dien_tich()
(để trống). Tạo lớp con HinhVuong
, HinhChuNhat
kế thừa và cài đặt phương thức này.
Bài 4: Viết class TaiKhoan
→ lớp TaiKhoanVIP
kế thừa, nhưng tính lãi suất cao hơn (ghi đè phương thức tinh_lai()
)
Kết luận
Kế thừa giúp bạn:
- Tái sử dụng code nhanh
- Tổ chức chương trình chuyên nghiệp
- Mở rộng dễ dàng khi yêu cầu thay đổi
Trong phần mềm lớn, kế thừa và hướng đối tượng là chìa khóa để tránh lặp lại, tránh rối mã nguồn, và dễ phát triển thêm tính năng.
Bài tiếp theo: Bài 20 – Viết thư viện (module) riêng để tái sử dụng
Bạn sẽ học cách đóng gói logic vào file .py
riêng và import đi nơi khác – cực kỳ cần thiết khi chương trình lớn hơn hoặc khi bạn làm việc theo nhóm.
Thảo luận