目次
1. Tổng quan về kế thừa trong Python
Trong Python, kế thừa là cơ chế cho phép lớp con thừa hưởng các chức năng và thuộc tính từ lớp cha. Nhờ đó, khả năng tái sử dụng mã được cải thiện và việc bảo trì trở nên hiệu quả hơn. Đây là một trong những khái niệm quan trọng của lập trình hướng đối tượng (OOP), đặc biệt hữu ích trong phát triển hệ thống quy mô lớn và các dự án dài hạn.Vai trò cơ bản của kế thừa
- Khả năng tái sử dụng mã: Vì có thể dùng lại chức năng của lớp đã viết cho các lớp khác, nên tránh được mã trùng lặp.
- Dễ bảo trì: Do thay đổi ở lớp cha tự động phản ánh xuống lớp con, việc sửa lỗi và mở rộng chức năng được thực hiện hiệu quả.
class ParentClass:
def greet(self):
print("Xin chào, tôi là lớp cha.")
class ChildClass(ParentClass):
def greet(self):
print("Xin chào, tôi là lớp con.")
Trong ví dụ này, ChildClass
ghi đè phương thức của ParentClass
。Vì phương thức greet
đã được ghi đè, nên lớp con sẽ hiển thị lời chào riêng của nó。2. Kế thừa đơn trong Python
Kế thừa đơn là hình thức trong đó một lớp con kế thừa các chức năng từ một lớp cha duy nhất. Đây là hình thức kế thừa cơ bản trong Python, vừa giữ cho mã đơn giản vừa đảm bảo khả năng mở rộng。Cú pháp cơ bản và ví dụ về kế thừa đơn
class Car:
def __init__(self, brand, color):
self.brand = brand
self.color = color
def describe(self):
print(f"Chiếc xe này là {self.brand} màu {self.color}。")
class ElectricCar(Car):
def __init__(self, brand, color, battery_size):
super().__init__(brand, color)
self.battery_size = battery_size
def describe_battery(self):
print(f"Dung lượng pin là {self.battery_size} kWh。")
Trong ví dụ này, lớp ElectricCar
kế thừa các chức năng của lớp Car
đồng thời bổ sung chức năng mô tả dung lượng pin. Sử dụng super()
để gọi constructor của lớp cha và khởi tạo các thuộc tính chung (thương hiệu và màu sắc)。
3. Ghi đè phương thức
Ghi đè là tính năng cho phép lớp con định nghĩa lại các phương thức của lớp cha. Nhờ đó, bạn có thể tận dụng các phương thức của lớp cha đồng thời thay đổi hành vi ở lớp con.Ví dụ về ghi đè
class Animal:
def speak(self):
print("Tiếng kêu của động vật")
class Dog(Animal):
def speak(self):
print("Gâu gâu!")
Trong ví dụ này, lớp Dog
ghi đè phương thức speak
của lớp Animal
. Nhờ vậy, với một thể hiện của lớp Dog
, sẽ in ra 「Gâu gâu」, còn với thể hiện của lớp Animal
sẽ hiển thị 「Tiếng kêu của động vật」.4. Đa kế thừa
Đa kế thừa cho phép một lớp con kế thừa từ nhiều lớp cha. Nhờ đó, bạn có thể hợp nhất các chức năng của các lớp khác nhau vào một lớp, nhưng cũng cần lưu ý vì việc triển khai có thể trở nên phức tạp.Ví dụ và lưu ý về đa kế thừa
class A:
def greet(self):
print("Lời chào của A")
class B:
def greet(self):
print("Lời chào của B")
class C(A, B):
pass
c = C()
c.greet() # Sẽ hiển thị "Lời chào của A" (theo MRO, lớp đầu tiên được ưu tiên)
Trong Python, MRO (Method Resolution Order) quyết định phương thức của lớp cha nào sẽ được gọi. Để kiểm tra thứ tự này, hãy dùng C.mro()
. Đa kế thừa rất mạnh mẽ, nhưng cần chú ý đến xung đột giữa các lớp cha và thứ tự của phương thức khi sử dụng.5. Ví dụ thực tiễn về việc sử dụng kế thừa
Kế thừa hữu ích trong rất nhiều tình huống của lập trình hằng ngày. Chẳng hạn, trong hệ thống quản lý nhân viên của doanh nghiệp, bằng cách kế thừa từ một lớp nhân viên cơ bản để tạo ra các lớp có chức vụ cụ thể, ta có thể tái sử dụng và mở rộng mã.Ví dụ thực tiễn về hệ thống quản lý nhân viên
class Employee:
def __init__(self, first, last, pay):
self.first = first
self.last = last
self.pay = pay
def fullname(self):
return f'{self.first} {self.last}'
class Manager(Employee):
def __init__(self, first, last, pay, employees=None):
super().__init__(first, last, pay)
self.employees = employees if employees is not None else []
def add_employee(self, employee):
if employee not in self.employees:
self.employees.append(employee)
def print_employees(self):
for emp in self.employees:
print(emp.fullname())
Trong ví dụ này, lớp Manager
kế thừa từ lớp Employee
và bổ sung chức năng quản lý nhân viên. Vừa duy trì các chức năng chung của lớp cha, vừa mở rộng các chức năng theo từng chức vụ cụ thể.6. Thực tiễn tốt nhất về kế thừa và so sánh với composition
Kế thừa rất mạnh mẽ, nhưng nếu lạm dụng sẽ có nguy cơ làm mã trở nên phức tạp. Đặc biệt, đa kế thừa có thể làm mối quan hệ giữa các lớp trở nên phức tạp, vì vậy nên sử dụng một cách thận trọng. Trong những trường hợp như vậy, nên ưu tiên sử dụng composition thay vì kế thừa.Ví dụ về composition
Composition là một mẫu thiết kế trong đó một lớp sở hữu một lớp khác như một thành phần (instance) để ủy quyền chức năng.class Engine:
def start(self):
print("Động cơ đã khởi động.")
class Car:
def __init__(self, engine):
self.engine = engine
def start(self):
self.engine.start()
engine = Engine()
car = Car(engine)
car.start() # "Động cơ đã khởi động." sẽ được hiển thị
Như vậy, composition là cách chia sẻ chức năng giữa các lớp mà không cần dùng kế thừa. Bằng cách chỉ đưa vào những chức năng cần thiết, mã sẽ linh hoạt hơn và dễ quản lý hơn.