Skip to Content
Python🎯 Python OOPKế thừa (Inheritance)

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 pass

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ụ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)) # False

Constructor 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: IT

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)

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 pass

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 pass

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 pass

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 pass

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ụ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)!

Last updated on