Tính Kế Thừa (Inheritance) Và Đóng Gói (Encapsulation) Trong Python

Tạo bởi Hoàng Vũ, chỉnh sửa cuối lúc 2 tháng 2, 2025

Lập trình hướng đối tượng (OOP) trong Python có hai khái niệm quan trọng là kế thừa (inheritance)đóng gói (encapsulation). Đây là hai nguyên tắc giúp tăng khả năng tái sử dụng mã nguồn, bảo mật dữ liệu và tổ chức code một cách hiệu quả hơn.

1. Tính Kế Thừa (Inheritance)

Định Nghĩa

  • Kế thừa là cơ chế cho phép một lớp (lớp con) có thể sử dụng lại các thuộc tính và phương thức của một lớp khác (lớp cha).
  • Kế thừa giúp giảm trùng lặp code và mở rộng chức năng của lớp cha.

Cách Sử Dụng

Khai báo lớp con kế thừa lớp cha bằng cách đặt tên lớp cha trong dấu ngoặc đơn:

class LopCha:
    def __init__(self, ten):
        self.ten = ten

    def gioi_thieu(self):
        print(f"Tôi là {self.ten}")

# Lớp Con kế thừa Lớp Cha
class LopCon(LopCha):
    def __init__(self, ten, tuoi):
        super().__init__(ten)  # Gọi constructor của lớp cha
        self.tuoi = tuoi

    def thong_tin(self):
        print(f"Tôi là {self.ten}, {self.tuoi} tuổi")

# Tạo đối tượng từ lớp con
nguoi = LopCon("An", 25)
nguoi.gioi_thieu()  # Gọi phương thức từ lớp cha
nguoi.thong_tin()   # Gọi phương thức từ lớp con

Kết quả:

Tôi là An  
Tôi là An, 25 tuổi  

super().__init__(ten) giúp gọi constructor của lớp cha để tránh lặp code.

Kế Thừa Nhiều Cấp

Một lớp con có thể tiếp tục được kế thừa bởi một lớp con khác:

class DongVat:
    def __init__(self, ten):
        self.ten = ten

    def keu(self):
        print("Động vật phát ra âm thanh")

class Cho(DongVat):
    def keu(self):
        print("Gâu gâu!")

class ChoCon(Cho):
    def mo_ta(self):
        print(f"{self.ten} là một chú chó con!")

cho_nho = ChoCon("Bobby")
cho_nho.keu()  # Gâu gâu!
cho_nho.mo_ta()  # Bobby là một chú chó con!

Kế Thừa Đa Lớp

Python hỗ trợ kế thừa từ nhiều lớp cha:

class Cha:
    def phuong_thuc_cha(self):
        print("Phương thức từ lớp cha")

class Me:
    def phuong_thuc_me(self):
        print("Phương thức từ lớp mẹ")

class Con(Cha, Me):
    pass

con = Con()
con.phuong_thuc_cha()  # Phương thức từ lớp cha
con.phuong_thuc_me()   # Phương thức từ lớp mẹ

2. Tính Đóng Gói (Encapsulation)

Định Nghĩa

  • Đóng gói là kỹ thuật giấu thông tin của một đối tượng, chỉ cho phép truy cập thông qua các phương thức được định nghĩa.
  • Giúp bảo vệ dữ liệu khỏi bị sửa đổi trực tiếp từ bên ngoài.

Cách Sử Dụng

Trong Python, có ba cấp độ truy cập thuộc tính:

  1. Public (ten): Có thể truy cập ở bất kỳ đâu.
  2. Protected (_ten): Chỉ nên truy cập trong nội bộ lớp và các lớp con.
  3. Private (__ten): Không thể truy cập trực tiếp từ bên ngoài lớp.

Ví Dụ: Thuộc Tính Public

class Nguoi:
    def __init__(self, ten):
        self.ten = ten  # Thuộc tính public

nguoi = Nguoi("An")
print(nguoi.ten)  # Có thể truy cập từ bên ngoài

Ví Dụ: Thuộc Tính Protected

class Nguoi:
    def __init__(self, ten, tuoi):
        self._tuoi = tuoi  # Thuộc tính protected

class SinhVien(Nguoi):
    def hien_thi(self):
        print(f"Tuổi: {self._tuoi}")  # Có thể truy cập từ lớp con

sv = SinhVien("Bình", 20)
sv.hien_thi()  # Tuổi: 20

_tuoi chỉ nên được sử dụng trong lớp và lớp con, nhưng vẫn có thể truy cập từ bên ngoài.

Ví Dụ: Thuộc Tính Private

class Nguoi:
    def __init__(self, ten, mat_khau):
        self.__mat_khau = mat_khau  # Thuộc tính private

    def hien_thi_mat_khau(self):
        print(self.__mat_khau)  # Truy cập được trong lớp

nguoi = Nguoi("An", "123456")
# print(nguoi.__mat_khau)  # Lỗi: Không thể truy cập trực tiếp
nguoi.hien_thi_mat_khau()  # 123456

__mat_khau không thể bị truy cập trực tiếp từ bên ngoài lớp.

Getter và Setter

Để truy cập và thay đổi thuộc tính private, dùng gettersetter:

class TaiKhoan:
    def __init__(self, so_du):
        self.__so_du = so_du  # Thuộc tính private

    def get_so_du(self):  # Getter
        return self.__so_du

    def set_so_du(self, so_moi):  # Setter
        if so_moi >= 0:
            self.__so_du = so_moi
        else:
            print("Số dư không hợp lệ!")

# Tạo đối tượng
tk = TaiKhoan(1000)
print(tk.get_so_du())  # 1000

tk.set_so_du(2000)  # Cập nhật số dư
print(tk.get_so_du())  # 2000

tk.set_so_du(-500)  # Lỗi: Số dư không hợp lệ!

3. Tổng Kết

Tính Chất Định Nghĩa Ví Dụ
Kế thừa (Inheritance) Lớp con có thể sử dụng lại các thuộc tính và phương thức của lớp cha class LopCon(LopCha)
Đóng gói (Encapsulation) Hạn chế truy cập trực tiếp vào dữ liệu bên trong lớp, bảo vệ dữ liệu __private, _protected, getter/setter

Khi nào dùng kế thừa?

  • Khi muốn tạo lớp mới nhưng vẫn giữ lại các tính năng của lớp cũ.
  • Giúp giảm trùng lặp code và dễ mở rộng.

Khi nào dùng đóng gói?

  • Khi muốn bảo vệ dữ liệu quan trọng, không cho phép sửa đổi trực tiếp.
  • Khi cần kiểm soát cách dữ liệu được truy xuất hoặc cập nhật.

Hiểu và sử dụng đúng kế thừa & đóng gói sẽ giúp code của bạn trở nên chuyên nghiệp hơn!

Website Logo

Với hơn 10 năm kinh nghiệm lập trình web và từng làm việc với nhiều framework, ngôn ngữ như PHP, JavaScript, React, jQuery, CSS, HTML, CakePHP, Laravel..., tôi hy vọng những kiến thức được chia sẻ tại đây sẽ hữu ích và thiết thực cho các bạn.

Bình luận

Website Logo

Chào, tôi là Vũ. Đây là blog hướng dẫn lập trình của tôi.

Liên hệ công việc qua email dưới đây.

lhvuctu@gmail.com

Chúng Tôi Trên

Bạn đang muốn học về lập trình website?

Bạn cần nâng cao kiến thức chuyên nghiệp hơn để nâng cao cơ hội nghề nghiệp? Liên hệ