本文目录导读:

在Python中重写父类方法(override)是面向对象编程的重要特性,以下是详细的介绍和案例:
基本重写方法
class Animal:
def make_sound(self):
print("动物的叫声")
def move(self):
print("动物在移动")
class Dog(Animal):
# 重写父类的 make_sound 方法
def make_sound(self):
print("汪汪汪!")
class Cat(Animal):
# 重写父类的 make_sound 方法
def make_sound(self):
print("喵喵喵!")
# 使用示例
dog = Dog()
cat = Cat()
dog.make_sound() # 输出:汪汪汪!
cat.make_sound() # 输出:喵喵喵!
dog.move() # 输出:动物在移动(使用父类方法)
调用父类方法(使用 super())
class Vehicle:
def __init__(self, brand, model):
self.brand = brand
self.model = model
print(f"父类构造方法:{self.brand} {self.model}")
def info(self):
return f"品牌:{self.brand},型号:{self.model}"
class Car(Vehicle):
def __init__(self, brand, model, color):
# 调用父类的构造方法
super().__init__(brand, model)
self.color = color
print(f"子类构造方法:颜色 = {self.color}")
# 重写父类的 info 方法
def info(self):
# 调用父类的 info 方法并扩展
base_info = super().info()
return f"{base_info},颜色:{self.color}"
# 使用示例
my_car = Car("Toyota", "Camry", "红色")
print(my_car.info())
# 输出:
# 父类构造方法:Toyota Camry
# 子类构造方法:颜色 = 红色
# 品牌:Toyota,型号:Camry,颜色:红色
完整重写案例:员工管理系统
class Employee:
"""员工基类"""
def __init__(self, name, employee_id):
self.name = name
self.employee_id = employee_id
def calculate_salary(self):
"""计算工资(抽象方法)"""
raise NotImplementedError("子类必须实现此方法")
def work(self):
"""工作方法"""
return f"{self.name}(工号:{self.employee_id}) 正在工作"
def get_info(self):
"""获取员工信息"""
return f"员工信息:{self.name},工号:{self.employee_id}"
class Developer(Employee):
"""开发人员"""
def __init__(self, name, employee_id, project_count):
super().__init__(name, employee_id)
self.project_count = project_count
# 重写 calculate_salary 方法
def calculate_salary(self):
base_salary = 8000
project_bonus = self.project_count * 2000
return base_salary + project_bonus
# 重写 work 方法
def work(self):
return f"{self.name} 正在写代码,参与 {self.project_count} 个项目"
# 重写 get_info 方法
def get_info(self):
base_info = super().get_info()
return f"{base_info},职位:开发,参与项目数:{self.project_count}"
class Manager(Employee):
"""管理人员"""
def __init__(self, name, employee_id, department_size):
super().__init__(name, employee_id)
self.department_size = department_size
# 重写 calculate_salary 方法
def calculate_salary(self):
base_salary = 12000
management_bonus = self.department_size * 1000
return base_salary + management_bonus
# 重写 work 方法
def work(self):
return f"{self.name} 正在管理团队,负责 {self.department_size} 人"
# 重写 get_info 方法
def get_info(self):
base_info = super().get_info()
return f"{base_info},职位:经理,管理人数:{self.department_size}"
# 使用示例
employees = [
Developer("张三", "D001", 3),
Developer("李四", "D002", 5),
Manager("王五", "M001", 8)
]
print("员工信息报告:")
print("-" * 40)
for emp in employees:
print(emp.get_info())
print(emp.work())
print(f"工资:{emp.calculate_salary():,}元")
print("-" * 40)
使用 @property 重写属性方法
class Shape:
def __init__(self, width, height):
self._width = width
self._height = height
@property
def area(self):
"""面积计算"""
raise NotImplementedError("子类必须实现")
@property
def perimeter(self):
"""周长计算"""
raise NotImplementedError("子类必须实现")
class Rectangle(Shape):
def __init__(self, width, height):
super().__init__(width, height)
# 重写 area 属性
@property
def area(self):
return self._width * self._height
# 重写 perimeter 属性
@property
def perimeter(self):
return 2 * (self._width + self._height)
class Square(Shape):
def __init__(self, side):
super().__init__(side, side)
# 重写 area 属性
@property
def area(self):
return self._width ** 2
# 重写 perimeter 属性
@property
def perimeter(self):
return 4 * self._width
# 使用示例
rect = Rectangle(5, 3)
square = Square(4)
print(f"矩形:宽={rect._width},高={rect._height}")
print(f"面积:{rect.area},周长:{rect.perimeter}")
# 输出:矩形:宽=5,高=3
# 输出:面积:15,周长:16
print(f"\n正方形:边长={square._width}")
print(f"面积:{square.area},周长:{square.perimeter}")
# 输出:正方形:边长=4
# 输出:面积:16,周长:16
重写静态方法和类方法
class DataProcessor:
@staticmethod
def process_data(data):
return f"原始数据:{data}"
@classmethod
def create_from_config(cls, config):
return f"从配置创建实例:{config}"
class AdvancedProcessor(DataProcessor):
# 重写静态方法
@staticmethod
def process_data(data):
processed = super(AdvancedProcessor, AdvancedProcessor).process_data(data) if False else ""
return f"进阶处理数据:{data}(已优化)"
# 重写类方法
@classmethod
def create_from_config(cls, config):
base_result = super().create_from_config(config)
return f"{base_result}(使用进阶策略)"
# 使用示例
print(DataProcessor.process_data("测试")) # 输出:原始数据:测试
print(AdvancedProcessor.process_data("测试")) # 输出:进阶处理数据:测试(已优化)
print(DataProcessor.create_from_config("配置A")) # 输出:从配置创建实例:配置A
print(AdvancedProcessor.create_from_config("配置A")) # 输出:从配置创建实例:配置A(使用进阶策略)
注意事项和最佳实践
class Base:
def __init__(self):
self._name = "Base"
def method(self, x, y):
return x + y
class Derived(Base):
def __init__(self):
super().__init__()
self._name = "Derived"
# 正确:参数数量一致
def method(self, x, y):
# 调用父类方法
result = super().method(x, y)
return result * 2
# 错误示例(会破坏多态):
# def method(self, x): # 参数不同
# pass
# 使用示例
d = Derived()
print(d.method(3, 4)) # 输出:14((3+4)*2)
- 重写原则:子类方法签名(名称和参数)要与父类一致
- 使用 super():在重写方法中调用父类方法,避免重复代码
- 保持兼容:重写方法应该接收相同的参数并返回兼容的类型
- 遵守 LSP:子类应该能替换父类对象而不影响程序正确性
- 使用装饰器:重写 @property、@staticmethod、@classmethod 时要使用相应的装饰器
通过合理使用方法重写,可以构建灵活、可扩展的面向对象程序,实现代码复用和功能特化。