Kế thừa (Inheritance)
Inheritance là gì?
Phần tiêu đề “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?
Phần tiêu đề “Tại sao cần Inheritance?”1. Tái sử dụng code (Code Reusability)
Phần tiêu đề “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
Phần tiêu đề “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
Phần tiêu đề “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
Phần tiêu đề “4. Polymorphism”Hỗ trợ đa hình - một trong những trụ cột của OOP.
Cú pháp
Phần tiêu đề “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
Phần tiêu đề “Ví 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ụngdog = Dog("Buddy")dog.speak() # Kế thừa từ Animal: Buddy đang phát ra tiếng kêudog.move() # Kế thừa từ Animal: Buddy đang di chuyểndog.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êucat.meow() # Kitty kêu: Meo meo!Kiểm tra quan hệ kế thừa
Phần tiêu đề “Kiểm tra quan hệ kế thừa”class Animal: pass
class Dog(Animal): pass
dog = Dog()
# Kiểm tra instanceprint(isinstance(dog, Dog)) # Trueprint(isinstance(dog, Animal)) # True
# Kiểm tra subclassprint(issubclass(Dog, Animal)) # Trueprint(issubclass(Animal, Dog)) # FalseConstructor trong Inheritance
Phần tiêu đề “Constructor trong Inheritance”Cách 1: Không gọi constructor của class cha
Phần tiêu đề “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ị)
Phần tiêu đề “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)
Phần tiêu đề “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!")
# Testanimals = [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()
Phần tiêu đề “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)
Phần tiêu đề “Multiple 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)
Phần tiêu đề “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 MROprint(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
Phần tiêu đề “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ụngprint("=== 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)
Phần tiêu đề “Levels of Inheritance (Cấp độ kế thừa)”Single Inheritance (Đơn kế thừa)
Phần tiêu đề “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)
Phần tiêu đề “Multilevel 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)
Phần tiêu đề “Hierarchical 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)
Phần tiêu đề “Multiple 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
Phần tiêu đề “Ví 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ụngdev = Developer("An", 25, "DEV001", 15000000, ["Python", "JavaScript"])dev.introduce() # Tôi là An, 25 tuổidev.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ổimanager.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)
Phần tiêu đề “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()}") # 15print(f"Chu vi: {rect.perimeter()}") # 16rect.display_color() # Màu sắc: Xanh
circle = Circle(5, "Đỏ")print(f"Diện tích: {circle.area():.2f}") # 78.54print(f"Chu vi: {circle.perimeter():.2f}") # 31.42circle.display_color() # Màu sắc: ĐỏTổng kết
Phần tiêu đề “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)!