Kế thừa (Inheritance)
Inheritance là gì?
Inheritance (Kế thừa) là khả năng tạo một class mới (class con) dựa trên class đã có (class cha). Class con sẽ:
- Thừa hưởng tất cả thuộc tính và phương thức từ class cha
- Có thể thêm thuộc tính và phương thức mới
- Có thể ghi đè (override) phương thức của class cha
Tại sao cần Inheritance?
1. Tái sử dụng code (Code Reusability)
Không cần viết lại code đã có, chỉ cần kế thừa.
2. Mở rộng chức năng
Dễ dàng thêm tính năng mới mà không làm thay đổi code cũ.
3. Tổ chức code tốt hơn
Tạo cấu trúc phân cấp logic, dễ hiểu và bảo trì.
4. Polymorphism
Hỗ trợ đa hình - một trong những trụ cột của OOP.
Cú pháp
class ParentClass:
# Code của class cha
pass
class ChildClass(ParentClass):
# Class con kế thừa từ class cha
passVí dụ cơ bản
# Class cha (Parent/Base/Super class)
class Animal:
def __init__(self, name):
self.name = name
def speak(self):
print(f"{self.name} đang phát ra tiếng kêu")
def move(self):
print(f"{self.name} đang di chuyển")
# Class con (Child/Derived/Sub class)
class Dog(Animal):
def bark(self):
print(f"{self.name} sủa: Gâu gâu!")
class Cat(Animal):
def meow(self):
print(f"{self.name} kêu: Meo meo!")
# Sử dụng
dog = Dog("Buddy")
dog.speak() # Kế thừa từ Animal: Buddy đang phát ra tiếng kêu
dog.move() # Kế thừa từ Animal: Buddy đang di chuyển
dog.bark() # Phương thức riêng: Buddy sủa: Gâu gâu!
cat = Cat("Kitty")
cat.speak() # Kitty đang phát ra tiếng kêu
cat.meow() # Kitty kêu: Meo meo!Kiểm tra quan hệ kế thừa
class Animal:
pass
class Dog(Animal):
pass
dog = Dog()
# Kiểm tra instance
print(isinstance(dog, Dog)) # True
print(isinstance(dog, Animal)) # True
# Kiểm tra subclass
print(issubclass(Dog, Animal)) # True
print(issubclass(Animal, Dog)) # FalseConstructor trong Inheritance
Cách 1: Không gọi constructor của class cha
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
class Student(Person):
def __init__(self, name, age, student_id):
# Gọi constructor của class cha
Person.__init__(self, name, age)
# Thêm thuộc tính mới
self.student_id = student_id
student = Student("An", 20, "SV001")
print(f"{student.name}, {student.age} tuổi, MSV: {student.student_id}")Cách 2: Dùng super() (Khuyến nghị)
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
class Student(Person):
def __init__(self, name, age, student_id, gpa):
super().__init__(name, age) # Gọi constructor của class cha
self.student_id = student_id
self.gpa = gpa
def display_info(self):
print(f"Sinh viên: {self.name}")
print(f"Tuổi: {self.age}")
print(f"MSV: {self.student_id}")
print(f"GPA: {self.gpa}")
student = Student("Bình", 21, "SV002", 3.5)
student.display_info()Method Overriding (Ghi đè phương thức)
Class con có thể định nghĩa lại phương thức của class cha.
class Animal:
def __init__(self, name):
self.name = name
def speak(self):
print(f"{self.name} phát ra tiếng kêu")
class Dog(Animal):
def speak(self): # Override phương thức speak()
print(f"{self.name} sủa: Gâu gâu!")
class Cat(Animal):
def speak(self): # Override phương thức speak()
print(f"{self.name} kêu: Meo meo!")
class Bird(Animal):
def speak(self): # Override phương thức speak()
print(f"{self.name} hót: Chip chip!")
# Test
animals = [Dog("Buddy"), Cat("Kitty"), Bird("Tweety")]
for animal in animals:
animal.speak()
# Buddy sủa: Gâu gâu!
# Kitty kêu: Meo meo!
# Tweety hót: Chip chip!Gọi phương thức của class cha với super()
class Employee:
def __init__(self, name, salary):
self.name = name
self.salary = salary
def display_info(self):
print(f"Nhân viên: {self.name}")
print(f"Lương: {self.salary:,}đ")
class Manager(Employee):
def __init__(self, name, salary, department):
super().__init__(name, salary)
self.department = department
def display_info(self):
super().display_info() # Gọi phương thức của class cha
print(f"Bộ phận: {self.department}")
manager = Manager("Nguyễn Văn A", 20000000, "IT")
manager.display_info()
# Nhân viên: Nguyễn Văn A
# Lương: 20,000,000đ
# Bộ phận: ITMultiple Inheritance (Đa kế thừa)
Python cho phép một class kế thừa từ nhiều class cha.
class Flyable:
def fly(self):
print("Tôi có thể bay!")
class Swimmable:
def swim(self):
print("Tôi có thể bơi!")
class Duck(Flyable, Swimmable):
def __init__(self, name):
self.name = name
def quack(self):
print(f"{self.name}: Quack quack!")
duck = Duck("Donald")
duck.fly() # Tôi có thể bay!
duck.swim() # Tôi có thể bơi!
duck.quack() # Donald: Quack quack!Method Resolution Order (MRO)
Khi có đa kế thừa, Python dùng MRO để quyết định thứ tự tìm kiếm phương thức.
class A:
def show(self):
print("A")
class B(A):
def show(self):
print("B")
class C(A):
def show(self):
print("C")
class D(B, C):
pass
d = D()
d.show() # B (tìm theo thứ tự: D -> B -> C -> A)
# Xem MRO
print(D.__mro__)
# (<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>,
# <class '__main__.A'>, <class 'object'>)Ví dụ thực tế: Hệ thống quản lý phương tiện
class Vehicle:
"""Class cha cho tất cả phương tiện"""
def __init__(self, brand, model, year):
self.brand = brand
self.model = model
self.year = year
self.mileage = 0
def drive(self, distance):
self.mileage += distance
print(f"Đã di chuyển {distance}km. Tổng: {self.mileage}km")
def display_info(self):
print(f"{self.year} {self.brand} {self.model}")
print(f"Quãng đường: {self.mileage}km")
class Car(Vehicle):
"""Xe hơi"""
def __init__(self, brand, model, year, num_doors):
super().__init__(brand, model, year)
self.num_doors = num_doors
def display_info(self):
super().display_info()
print(f"Số cửa: {self.num_doors}")
class Motorcycle(Vehicle):
"""Xe máy"""
def __init__(self, brand, model, year, engine_cc):
super().__init__(brand, model, year)
self.engine_cc = engine_cc
def display_info(self):
super().display_info()
print(f"Dung tích: {self.engine_cc}cc")
def wheelie(self):
print("Đang bốc đầu!")
class ElectricCar(Car):
"""Xe điện"""
def __init__(self, brand, model, year, num_doors, battery_capacity):
super().__init__(brand, model, year, num_doors)
self.battery_capacity = battery_capacity
self.battery_level = 100
def charge(self, percent):
self.battery_level = min(100, self.battery_level + percent)
print(f"Đã sạc. Pin hiện tại: {self.battery_level}%")
def drive(self, distance):
battery_used = distance * 0.2 # Giả sử 1km tốn 0.2% pin
if self.battery_level >= battery_used:
super().drive(distance)
self.battery_level -= battery_used
print(f"Pin còn: {self.battery_level:.1f}%")
else:
print("Pin không đủ!")
def display_info(self):
super().display_info()
print(f"Dung lượng pin: {self.battery_capacity}kWh")
print(f"Mức pin: {self.battery_level}%")
# Sử dụng
print("=== XE HƠI ===")
car = Car("Toyota", "Camry", 2024, 4)
car.drive(100)
car.display_info()
print("\n=== XE MÁY ===")
bike = Motorcycle("Honda", "Wave", 2023, 110)
bike.drive(50)
bike.wheelie()
bike.display_info()
print("\n=== XE ĐIỆN ===")
tesla = ElectricCar("Tesla", "Model 3", 2024, 4, 75)
tesla.drive(200)
tesla.charge(30)
tesla.display_info()Levels of Inheritance (Cấp độ kế thừa)
Single Inheritance (Đơn kế thừa)
class A:
pass
class B(A): # B kế thừa từ A
passMultilevel Inheritance (Kế thừa nhiều cấp)
class A:
pass
class B(A): # B kế thừa từ A
pass
class C(B): # C kế thừa từ B
passHierarchical Inheritance (Kế thừa phân cấp)
class A:
pass
class B(A): # B kế thừa từ A
pass
class C(A): # C kế thừa từ A
passMultiple Inheritance (Đa kế thừa)
class A:
pass
class B:
pass
class C(A, B): # C kế thừa từ cả A và B
passVí dụ: Hệ thống nhân viên
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def introduce(self):
print(f"Tôi là {self.name}, {self.age} tuổi")
class Employee(Person):
def __init__(self, name, age, employee_id, salary):
super().__init__(name, age)
self.employee_id = employee_id
self.salary = salary
def work(self):
print(f"{self.name} đang làm việc")
def get_salary(self):
return self.salary
class Developer(Employee):
def __init__(self, name, age, employee_id, salary, programming_languages):
super().__init__(name, age, employee_id, salary)
self.programming_languages = programming_languages
def code(self):
langs = ", ".join(self.programming_languages)
print(f"{self.name} đang code bằng {langs}")
def work(self): # Override
self.code()
class Manager(Employee):
def __init__(self, name, age, employee_id, salary, team_size):
super().__init__(name, age, employee_id, salary)
self.team_size = team_size
def manage(self):
print(f"{self.name} đang quản lý {self.team_size} người")
def work(self): # Override
self.manage()
# Sử dụng
dev = Developer("An", 25, "DEV001", 15000000, ["Python", "JavaScript"])
dev.introduce() # Tôi là An, 25 tuổi
dev.work() # An đang code bằng Python, JavaScript
manager = Manager("Bình", 35, "MNG001", 25000000, 10)
manager.introduce() # Tôi là Bình, 35 tuổi
manager.work() # Bình đang quản lý 10 người
print(f"Lương Dev: {dev.get_salary():,}đ")
print(f"Lương Manager: {manager.get_salary():,}đ")Abstract Base Class (ABC)
Class trừu tượng - class không thể tạo object trực tiếp, chỉ dùng để kế thừa.
from abc import ABC, abstractmethod
class Shape(ABC):
"""Class trừu tượng"""
def __init__(self, color):
self.color = color
@abstractmethod
def area(self):
"""Phương thức trừu tượng - bắt buộc class con phải implement"""
pass
@abstractmethod
def perimeter(self):
pass
def display_color(self):
print(f"Màu sắc: {self.color}")
class Rectangle(Shape):
def __init__(self, width, height, color):
super().__init__(color)
self.width = width
self.height = height
def area(self):
return self.width * self.height
def perimeter(self):
return 2 * (self.width + self.height)
class Circle(Shape):
def __init__(self, radius, color):
super().__init__(color)
self.radius = radius
def area(self):
return 3.14159 * self.radius ** 2
def perimeter(self):
return 2 * 3.14159 * self.radius
# shape = Shape("Đỏ") # Lỗi! Không thể tạo instance của ABC
rect = Rectangle(5, 3, "Xanh")
print(f"Diện tích: {rect.area()}") # 15
print(f"Chu vi: {rect.perimeter()}") # 16
rect.display_color() # Màu sắc: Xanh
circle = Circle(5, "Đỏ")
print(f"Diện tích: {circle.area():.2f}") # 78.54
print(f"Chu vi: {circle.perimeter():.2f}") # 31.42
circle.display_color() # Màu sắc: ĐỏTổng kết
- Inheritance cho phép tái sử dụng và mở rộng code
- Class con thừa hưởng thuộc tính và phương thức từ class cha
- Dùng
super()để gọi constructor và phương thức của class cha - Method overriding cho phép class con định nghĩa lại phương thức
- Python hỗ trợ multiple inheritance (đa kế thừa)
- Abstract Base Class định nghĩa interface bắt buộc các class con phải implement
Trong bài tiếp theo, chúng ta sẽ tìm hiểu về Encapsulation (Đóng gói)!