Đăng nhập

Bài 19: Kế thừa class – Tái sử dụng và mở rộng đối tượng

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 classobject, 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ừa ConNguoi, nó có tất cả thuộc tính và phương thức của ConNguoi, 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

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *

Đăng ký nhận tin mới

Nhận bài học, tài nguyên và cơ hội việc làm qua email hàng tuần.

Chúng tôi cam kết không spam. Bạn có thể hủy bất cứ lúc nào.