Python 进阶突破面向对象——继承(Inheritance)详解
继承是面向对象编程的四大支柱之一,它允许我们基于现有类创建新类,新类会继承父类的属性和方法,同时可以添加或修改功能。
一、继承的基本概念
1. 基本语法
class ParentClass:
# 父类定义
pass
class ChildClass(ParentClass):
# 子类定义
pass
2. 简单示例
class Animal:
def __init__(self, name):
self.name = name
def speak(self):
print(f"{self.name} makes a sound")
class Dog(Animal):
def speak(self):
print(f"{self.name} says woof!")
class Cat(Animal):
def speak(self):
print(f"{self.name} says meow!")
# 使用示例
animal = Animal("Generic Animal")
animal.speak() # Generic Animal makes a sound
dog = Dog("Buddy")
dog.speak() # Buddy says woof!
cat = Cat("Whiskers")
cat.speak() # Whiskers says meow!
二、继承的类型
1. 单继承
一个子类只继承一个父类(Python默认支持)
class Parent:
def parent_method(self):
print("Parent method")
class Child(Parent):
def child_method(self):
print("Child method")
c = Child()
c.parent_method() # 继承自Parent
c.child_method() # 自己的方法
2. 多继承
一个子类可以继承多个父类
class Father:
def father_method(self):
print("Father's method")
class Mother:
def mother_method(self):
print("Mother's method")
class Child(Father, Mother):
def child_method(self):
print("Child's method")
c = Child()
c.father_method() # 继承自Father
c.mother_method() # 继承自Mother
c.child_method() # 自己的方法
3. 多层继承(继承链)
class Grandparent:
def grandparent_method(self):
print("Grandparent's method")
class Parent(Grandparent):
def parent_method(self):
print("Parent's method")
class Child(Parent):
def child_method(self):
print("Child's method")
c = Child()
c.grandparent_method() # 继承自Grandparent
c.parent_method() # 继承自Parent
c.child_method() # 自己的方法
三、方法重写(Override)
子类可以重写父类的方法以改变其行为
class Vehicle:
def __init__(self, brand):
self.brand = brand
def drive(self):
print(f"{self.brand} is driving")
class Car(Vehicle):
def drive(self): # 重写父类方法
print(f"{self.brand} car is driving fast!")
class Truck(Vehicle):
def drive(self): # 重写父类方法
print(f"{self.brand} truck is driving slowly")
v = Vehicle("Generic")
v.drive() # Generic is driving
c = Car("Toyota")
c.drive() # Toyota car is driving fast!
t = Truck("Volvo")
t.drive() # Volvo truck is driving slowly
四、super()函数
super()用于调用父类的方法,常用于:
- 访问被重写的父类方法
- 在子类__init__中调用父类初始化方法
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def display_info(self):
print(f"Name: {self.name}, Age: {self.age}")
class Student(Person):
def __init__(self, name, age, student_id):
super().__init__(name, age) # 调用父类的__init__
self.student_id = student_id
def display_info(self):
super().display_info() # 调用父类的display_info
print(f"Student ID: {self.student_id}")
s = Student("Alice", 20, "S12345")
s.display_info()
# 输出:
# Name: Alice, Age: 20
# Student ID: S12345
五、方法解析顺序(MRO)
在多重继承中,Python使用C3线性化算法确定方法调用顺序,可以通过__mro__属性或mro()方法查看
class A:
def method(self):
print("A method")
class B(A):
def method(self):
print("B method")
class C(A):
def method(self):
print("C method")
class D(B, C):
pass
print(D.__mro__)
# 输出: (<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>)
d = D()
d.method() # 输出: B method (按照MRO顺序查找)
六、抽象基类(ABC)
使用abc模块可以定义抽象基类,强制子类实现特定方法
from abc import ABC, abstractmethod
class Shape(ABC):
@abstractmethod
def area(self):
pass
@abstractmethod
def perimeter(self):
pass
class Rectangle(Shape):
def __init__(self, width, height):
self.width = width
self.height = height
def area(self):
return self.width * self.height
def perimeter(self):
return 2 * (self.width + self.height)
# 必须实现所有抽象方法,否则会报错
r = Rectangle(5, 3)
print(r.area()) # 15
print(r.perimeter()) # 16
七、继承的实际应用示例
# 员工管理系统示例
class Employee:
def __init__(self, name, employee_id):
self.name = name
self.employee_id = employee_id
def display_info(self):
print(f"Employee: {self.name}, ID: {self.employee_id}")
def calculate_salary(self):
raise NotImplementedError("Subclass must implement this method")
class FullTimeEmployee(Employee):
def __init__(self, name, employee_id, monthly_salary):
super().__init__(name, employee_id)
self.monthly_salary = monthly_salary
def calculate_salary(self):
return self.monthly_salary
class PartTimeEmployee(Employee):
def __init__(self, name, employee_id, hours_worked, hourly_rate):
super().__init__(name, employee_id)
self.hours_worked = hours_worked
self.hourly_rate = hourly_rate
def calculate_salary(self):
return self.hours_worked * self.hourly_rate
# 使用示例
full_time = FullTimeEmployee("Alice", "FT001", 5000)
part_time = PartTimeEmployee("Bob", "PT001", 80, 20)
employees = [full_time, part_time]
for emp in employees:
emp.display_info()
print(f"Salary: ${emp.calculate_salary()}")
print("-" * 30)
继承是代码复用的强大工具,合理使用继承可以:
- 减少代码重复
- 提高代码可维护性
- 建立清晰的类层次结构
- 实现多态行为
但也要注意不要过度使用继承,有时组合(composition)可能是更好的选择。