Python bài 14: Đóng gói, property, kế thừa và đa hình
- 18-10-2026
- Toanngo92
- 0 Comments
Giáo trình Python miễn phí · Chương 7/12: Lập trình hướng đối tượng · Bài 14/24.
Mục lục
Mục tiêu bài học
Kiểm soát dữ liệu qua property, mở rộng hành vi bằng kế thừa và hiểu đa hình theo cách Python.
Đóng gói bằng giao diện rõ ràng
Đóng gói không chỉ là đặt dấu gạch dưới trước tên. Mục tiêu là cho phần còn lại của chương trình một cách dùng ổn định và giữ trạng thái hợp lệ. Quy ước _ten cho biết thuộc tính thuộc nội bộ; __ten có cơ chế name mangling nhằm tránh đụng tên ở lớp con, không phải bảo mật tuyệt đối.
property cho phép dùng cú pháp thuộc tính trong khi vẫn kiểm tra khi gán. Setter cần xử lý quy tắc và lưu vào tên nội bộ khác; nếu tự gán lại property đó bên trong setter sẽ tạo đệ quy vô hạn.
class SanPham:
def __init__(self, ten, gia):
self.ten = ten
self.gia = gia
@property
def gia(self):
return self._gia
@gia.setter
def gia(self, gia_tri):
if gia_tri < 0:
raise ValueError("Giá không được âm")
self._gia = gia_tri
def __str__(self):
return f"{self.ten}: {self.gia:,} đồng"
sp = SanPham("Sách Python", 120000)
sp.gia = 135000
print(sp)
Kết quả:
Sách Python: 135,000 đồng
Kế thừa và super()
Kế thừa phù hợp khi lớp con có thể được dùng như một dạng của lớp cha. Lớp con có thể bổ sung trạng thái và ghi đè phương thức. super() gọi theo thứ tự phân giải phương thức, giúp phối hợp hành vi kế thừa; với kế thừa đơn có thể hình dung là tiếp tục đến lớp cha.
Không dùng kế thừa chỉ để tiết kiệm vài dòng. Nếu một đối tượng chỉ cần sử dụng một thành phần khác, composition thường hợp lý hơn: lớp DonHang chứa danh sách SanPham thay vì kế thừa SanPham.
from abc import ABC, abstractmethod
class ThongBao(ABC):
@abstractmethod
def noi_dung(self):
pass
class Email(ThongBao):
def noi_dung(self):
return "Gửi email xác nhận"
class TinNhan(ThongBao):
def noi_dung(self):
return "Gửi tin nhắn xác nhận"
for kenh in [Email(), TinNhan()]:
print(kenh.noi_dung())
Kết quả:
Gửi email xác nhận Gửi tin nhắn xác nhận
Đa hình và giao thức hành vi
Cùng lời gọi noi_dung() có kết quả tùy đối tượng nhận lời gọi. Đây là đa hình ở thời điểm chạy. Python còn dùng duck typing: quan tâm đối tượng đáp ứng hành vi cần thiết, không bắt buộc mọi tình huống đều có cùng lớp cha. ABC hữu ích khi muốn mô tả giao diện và ngăn khởi tạo lớp còn thiếu phương thức trừu tượng.
Việc viết hai phương thức cùng tên trong một lớp không tạo overload theo kiểu tham số như một số ngôn ngữ khác; định nghĩa sau ghi đè định nghĩa trước. Dùng tham số mặc định hoặc thiết kế hàm rõ ràng để xử lý các cách gọi khác nhau.
Lỗi thường gặp và lưu ý
- Name mangling không che giấu được dữ liệu khỏi người có quyền chạy chương trình.
- Không kế thừa sâu khi chỉ cần vài thành phần kết hợp; ưu tiên mô hình dễ đọc và dễ thay thế.
Ghi nhớ
Property duy trì trạng thái hợp lệ; kế thừa mở rộng một quan hệ phù hợp; đa hình giúp cùng đoạn điều phối làm việc với nhiều cách triển khai.

