Python教程(二十三):继承和多态
off999 2025-08-05 20:27 13 浏览 0 评论
昨天,我们学习了面向对象编程基础,掌握了类和对象的核心概念。今天,我们将学习继承和多态 — 面向对象编程中最重要的两个概念。
继承让您能够创建层次化的类结构,而多态则提供了灵活的方法调用机制。
今天您将学习什么
- 什么是继承以及如何实现继承
- 单继承和多继承
- 方法重写和super()函数
- 多态的概念和实现
- 真实世界示例:动物系统、图形系统、员工管理
什么是继承?
继承是面向对象编程的核心概念之一,它允许一个类(子类)继承另一个类(父类)的属性和方法。继承实现了代码重用和层次化设计。
继承的优势:
- 代码重用:避免重复编写相同的代码
- 层次化设计:创建逻辑清晰的类层次结构
- 扩展性:轻松添加新功能而不影响现有代码
- 维护性:集中管理共同的属性和方法
1. 基本继承
单继承示例
class Animal:
"""动物基类"""
def __init__(self, name, species):
self.name = name
self.species = species
self.energy = 100
def eat(self, food):
"""吃东西"""
self.energy += 20
print(f"{self.name}吃了{food},能量增加到{self.energy}")
def sleep(self):
"""睡觉"""
self.energy += 30
print(f"{self.name}睡觉了,能量增加到{self.energy}")
def make_sound(self):
"""发出声音(基类方法)"""
print(f"{self.name}发出了声音")
def get_info(self):
"""获取动物信息"""
return f"名字:{self.name},种类:{self.species},能量:{self.energy}"
class Dog(Animal):
"""狗类 - 继承自Animal"""
def __init__(self, name, breed):
# 调用父类的构造函数
super().__init__(name, "狗")
self.breed = breed
def make_sound(self):
"""重写父类方法"""
print(f"{self.name}说:汪汪!")
def fetch(self, item):
"""狗特有的方法"""
self.energy -= 10
print(f"{self.name}去捡{item},能量减少到{self.energy}")
def get_info(self):
"""重写父类方法"""
base_info = super().get_info()
return f"{base_info},品种:{self.breed}"
class Cat(Animal):
"""猫类 - 继承自Animal"""
def __init__(self, name, color):
super().__init__(name, "猫")
self.color = color
def make_sound(self):
"""重写父类方法"""
print(f"{self.name}说:喵喵!")
def climb(self, height):
"""猫特有的方法"""
self.energy -= 15
print(f"{self.name}爬到了{height}米高,能量减少到{self.energy}")
def get_info(self):
"""重写父类方法"""
base_info = super().get_info()
return f"{base_info},颜色:{self.color}"
# 使用继承
dog = Dog("旺财", "金毛")
cat = Cat("咪咪", "橘色")
print(dog.get_info())
print(cat.get_info())
dog.make_sound()
cat.make_sound()
dog.fetch("球")
cat.climb(2)
dog.eat("狗粮")
cat.sleep()
2. 方法重写和super()函数
方法重写详解
class Vehicle:
"""交通工具基类"""
def __init__(self, brand, model, year):
self.brand = brand
self.model = model
self.year = year
self.speed = 0
def start_engine(self):
"""启动引擎"""
print(f"{self.brand} {self.model}的引擎启动了")
def accelerate(self, amount):
"""加速"""
self.speed += amount
print(f"速度增加到{self.speed}km/h")
def brake(self, amount):
"""刹车"""
self.speed = max(0, self.speed - amount)
print(f"速度减少到{self.speed}km/h")
def get_info(self):
"""获取车辆信息"""
return f"{self.year}年 {self.brand} {self.model}"
class Car(Vehicle):
"""汽车类"""
def __init__(self, brand, model, year, fuel_type):
# 调用父类构造函数
super().__init__(brand, model, year)
self.fuel_type = fuel_type
self.doors = 4
def start_engine(self):
"""重写启动引擎方法"""
print(f"汽车引擎启动,燃料类型:{self.fuel_type}")
super().start_engine() # 调用父类方法
def honk(self):
"""汽车特有的方法"""
print("汽车鸣笛:滴滴!")
def get_info(self):
"""重写获取信息方法"""
base_info = super().get_info()
return f"{base_info},燃料:{self.fuel_type},车门数:{self.doors}"
class Motorcycle(Vehicle):
"""摩托车类"""
def __init__(self, brand, model, year, engine_size):
super().__init__(brand, model, year)
self.engine_size = engine_size
self.wheels = 2
def start_engine(self):
"""重写启动引擎方法"""
print(f"摩托车引擎启动,排量:{self.engine_size}cc")
super().start_engine()
def wheelie(self):
"""摩托车特有的方法"""
print("摩托车翘头!")
def get_info(self):
"""重写获取信息方法"""
base_info = super().get_info()
return f"{base_info},排量:{self.engine_size}cc,轮子数:{self.wheels}"
# 使用继承和方法重写
car = Car("丰田", "凯美瑞", 2023, "汽油")
motorcycle = Motorcycle("本田", "CBR600", 2022, 600)
print(car.get_info())
print(motorcycle.get_info())
car.start_engine()
motorcycle.start_engine()
car.honk()
motorcycle.wheelie()
car.accelerate(50)
motorcycle.accelerate(80)
真实世界示例1:图形系统
import math
class Shape:
"""图形基类"""
def __init__(self, color="黑色"):
self.color = color
def area(self):
"""计算面积(抽象方法)"""
raise NotImplementedError("子类必须实现area方法")
def perimeter(self):
"""计算周长(抽象方法)"""
raise NotImplementedError("子类必须实现perimeter方法")
def get_info(self):
"""获取图形信息"""
return f"颜色:{self.color},面积:{self.area():.2f},周长:{self.perimeter():.2f}"
class Circle(Shape):
"""圆形类"""
def __init__(self, radius, color="红色"):
super().__init__(color)
self.radius = radius
def area(self):
"""计算圆形面积"""
return math.pi * self.radius ** 2
def perimeter(self):
"""计算圆形周长"""
return 2 * math.pi * self.radius
def get_info(self):
"""重写获取信息方法"""
base_info = super().get_info()
return f"圆形 - 半径:{self.radius},{base_info}"
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)
def is_square(self):
"""判断是否为正方形"""
return self.width == self.height
def get_info(self):
"""重写获取信息方法"""
base_info = super().get_info()
square_info = "(正方形)" if self.is_square() else ""
return f"矩形{square_info} - 宽:{self.width},高:{self.height},{base_info}"
class Triangle(Shape):
"""三角形类"""
def __init__(self, side1, side2, side3, color="绿色"):
super().__init__(color)
self.side1 = side1
self.side2 = side2
self.side3 = side3
def area(self):
"""计算三角形面积(海伦公式)"""
s = (self.side1 + self.side2 + self.side3) / 2
return math.sqrt(s * (s - self.side1) * (s - self.side2) * (s - self.side3))
def perimeter(self):
"""计算三角形周长"""
return self.side1 + self.side2 + self.side3
def is_equilateral(self):
"""判断是否为等边三角形"""
return self.side1 == self.side2 == self.side3
def is_isosceles(self):
"""判断是否为等腰三角形"""
return (self.side1 == self.side2 or
self.side1 == self.side3 or
self.side2 == self.side3)
def get_info(self):
"""重写获取信息方法"""
base_info = super().get_info()
triangle_type = "等边三角形" if self.is_equilateral() else "等腰三角形" if self.is_isosceles() else "普通三角形"
return f"{triangle_type} - 边长:{self.side1}, {self.side2}, {self.side3},{base_info}"
# 使用图形系统
shapes = [
Circle(5),
Rectangle(4, 6),
Rectangle(3, 3), # 正方形
Triangle(3, 4, 5),
Triangle(5, 5, 5), # 等边三角形
Triangle(4, 4, 6) # 等腰三角形
]
print("图形信息:")
for shape in shapes:
print(f" {shape.get_info()}")
# 多态示例
def print_shape_info(shape):
"""打印图形信息的函数(多态)"""
print(f"图形:{shape.get_info()}")
print("\n使用多态函数:")
for shape in shapes:
print_shape_info(shape)
真实世界示例2:员工管理系统
from datetime import datetime
class Employee:
"""员工基类"""
def __init__(self, name, employee_id, salary):
self.name = name
self.employee_id = employee_id
self.salary = salary
self.hire_date = datetime.now()
self.department = "未分配"
def work(self):
"""工作(抽象方法)"""
print(f"{self.name}正在工作")
def get_salary(self):
"""获取工资"""
return self.salary
def get_info(self):
"""获取员工信息"""
return f"ID:{self.employee_id},姓名:{self.name},部门:{self.department},工资:{self.salary}元"
def __str__(self):
return self.get_info()
class Manager(Employee):
"""经理类"""
def __init__(self, name, employee_id, salary, team_size=0):
super().__init__(name, employee_id, salary)
self.department = "管理部"
self.team_size = team_size
self.bonus_rate = 0.2 # 奖金比例
def work(self):
"""重写工作方法"""
print(f"{self.name}正在管理团队,团队规模:{self.team_size}人")
def get_salary(self):
"""重写获取工资方法(包含奖金)"""
bonus = self.salary * self.bonus_rate
return self.salary + bonus
def manage_team(self):
"""管理团队"""
print(f"{self.name}正在召开团队会议")
def get_info(self):
"""重写获取信息方法"""
base_info = super().get_info()
return f"{base_info},团队规模:{self.team_size}人,总工资:{self.get_salary()}元"
class Developer(Employee):
"""开发人员类"""
def __init__(self, name, employee_id, salary, programming_language="Python"):
super().__init__(name, employee_id, salary)
self.department = "技术部"
self.programming_language = programming_language
self.projects = []
def work(self):
"""重写工作方法"""
print(f"{self.name}正在用{self.programming_language}编程")
def add_project(self, project_name):
"""添加项目"""
self.projects.append(project_name)
print(f"{self.name}加入了项目:{project_name}")
def get_info(self):
"""重写获取信息方法"""
base_info = super().get_info()
projects_str = ", ".join(self.projects) if self.projects else "无"
return f"{base_info},编程语言:{self.programming_language},项目:{projects_str}"
class Salesperson(Employee):
"""销售人员类"""
def __init__(self, name, employee_id, salary, commission_rate=0.1):
super().__init__(name, employee_id, salary)
self.department = "销售部"
self.commission_rate = commission_rate
self.sales_amount = 0
def work(self):
"""重写工作方法"""
print(f"{self.name}正在拜访客户")
def make_sale(self, amount):
"""完成销售"""
self.sales_amount += amount
commission = amount * self.commission_rate
print(f"{self.name}完成销售{amount}元,获得佣金{commission}元")
def get_salary(self):
"""重写获取工资方法(包含佣金)"""
commission = self.sales_amount * self.commission_rate
return self.salary + commission
def get_info(self):
"""重写获取信息方法"""
base_info = super().get_info()
return f"{base_info},销售额:{self.sales_amount}元,总工资:{self.get_salary()}元"
# 使用员工管理系统
employees = [
Manager("张经理", "M001", 8000, 5),
Developer("李开发", "D001", 6000, "Python"),
Developer("王开发", "D002", 6500, "Java"),
Salesperson("赵销售", "S001", 4000, 0.15)
]
# 多态示例
def employee_work(employee):
"""员工工作函数(多态)"""
employee.work()
def print_employee_salary(employee):
"""打印员工工资函数(多态)"""
print(f"{employee.name}的工资:{employee.get_salary()}元")
print("员工信息:")
for emp in employees:
print(f" {emp.get_info()}")
print("\n员工工作:")
for emp in employees:
employee_work(emp)
print("\n员工工资:")
for emp in employees:
print_employee_salary(emp)
# 特定员工操作
manager = employees[0]
developer = employees[1]
salesperson = employees[3]
manager.manage_team()
developer.add_project("电商平台")
developer.add_project("移动应用")
salesperson.make_sale(10000)
salesperson.make_sale(5000)
print("\n更新后的员工信息:")
for emp in employees:
print(f" {emp.get_info()}")
真实世界示例3:游戏角色系统
import random
class Character:
"""游戏角色基类"""
def __init__(self, name, level=1):
self.name = name
self.level = level
self.health = 100
self.max_health = 100
self.attack = 10
self.defense = 5
self.experience = 0
self.experience_to_next = 100
def attack_target(self, target):
"""攻击目标"""
damage = max(1, self.attack - target.defense)
target.take_damage(damage)
print(f"{self.name}攻击{target.name},造成{damage}点伤害")
def take_damage(self, damage):
"""受到伤害"""
self.health = max(0, self.health - damage)
if self.health == 0:
print(f"{self.name}被击败了!")
def heal(self, amount):
"""治疗"""
old_health = self.health
self.health = min(self.max_health, self.health + amount)
healed = self.health - old_health
print(f"{self.name}恢复了{healed}点生命值")
def gain_experience(self, amount):
"""获得经验"""
self.experience += amount
print(f"{self.name}获得{amount}点经验值")
while self.experience >= self.experience_to_next:
self.level_up()
def level_up(self):
"""升级"""
self.level += 1
self.experience -= self.experience_to_next
self.experience_to_next = int(self.experience_to_next * 1.5)
self.max_health += 20
self.health = self.max_health
self.attack += 5
self.defense += 2
print(f"{self.name}升级到{self.level}级!")
def is_alive(self):
"""检查是否存活"""
return self.health > 0
def get_status(self):
"""获取状态信息"""
return f"{self.name} Lv.{self.level} HP:{self.health}/{self.max_health} ATK:{self.attack} DEF:{self.defense}"
class Warrior(Character):
"""战士类"""
def __init__(self, name, level=1):
super().__init__(name, level)
self.max_health = 120
self.health = 120
self.attack = 15
self.defense = 8
self.rage = 0
self.max_rage = 100
def attack_target(self, target):
"""重写攻击方法"""
# 战士攻击有几率增加怒气
if random.random() < 0.3:
self.rage = min(self.max_rage, self.rage + 20)
print(f"{self.name}的怒气增加到{self.rage}")
# 怒气满时可以释放技能
if self.rage >= self.max_rage:
self.rage = 0
damage = self.attack * 2
target.take_damage(damage)
print(f"{self.name}释放技能,对{target.name}造成{damage}点伤害!")
else:
super().attack_target(target)
def shield_bash(self, target):
"""盾击技能"""
if self.rage >= 30:
self.rage -= 30
damage = self.attack + self.defense
target.take_damage(damage)
print(f"{self.name}使用盾击,对{target.name}造成{damage}点伤害")
else:
print("怒气不足,无法使用盾击")
class Mage(Character):
"""法师类"""
def __init__(self, name, level=1):
super().__init__(name, level)
self.max_health = 80
self.health = 80
self.attack = 8
self.defense = 3
self.mana = 100
self.max_mana = 100
def attack_target(self, target):
"""重写攻击方法"""
if self.mana >= 20:
# 魔法攻击
self.mana -= 20
damage = self.attack * 1.5
target.take_damage(damage)
print(f"{self.name}使用魔法攻击{target.name},造成{damage}点伤害")
else:
# 普通攻击
super().attack_target(target)
def fireball(self, target):
"""火球术"""
if self.mana >= 40:
self.mana -= 40
damage = self.attack * 2.5
target.take_damage(damage)
print(f"{self.name}释放火球术,对{target.name}造成{damage}点伤害!")
else:
print("法力不足,无法释放火球术")
def heal_spell(self, target):
"""治疗术"""
if self.mana >= 30:
self.mana -= 30
heal_amount = 30
target.heal(heal_amount)
print(f"{self.name}对{target.name}释放治疗术")
else:
print("法力不足,无法释放治疗术")
def get_status(self):
"""重写状态信息"""
base_status = super().get_status()
return f"{base_status} MP:{self.mana}/{self.max_mana}"
class Archer(Character):
"""弓箭手类"""
def __init__(self, name, level=1):
super().__init__(name, level)
self.max_health = 90
self.health = 90
self.attack = 12
self.defense = 4
self.arrows = 20
self.max_arrows = 20
def attack_target(self, target):
"""重写攻击方法"""
if self.arrows > 0:
# 弓箭攻击
self.arrows -= 1
damage = self.attack * 1.3
target.take_damage(damage)
print(f"{self.name}射箭攻击{target.name},造成{damage}点伤害,剩余箭矢:{self.arrows}")
else:
# 近战攻击
super().attack_target(target)
def multi_shot(self, targets):
"""多重射击"""
if self.arrows >= 3:
self.arrows -= 3
damage = self.attack * 0.8
for target in targets:
target.take_damage(damage)
print(f"{self.name}使用多重射击,对多个目标造成{damage}点伤害")
else:
print("箭矢不足,无法使用多重射击")
def restock_arrows(self, amount):
"""补充箭矢"""
self.arrows = min(self.max_arrows, self.arrows + amount)
print(f"{self.name}补充了{amount}支箭矢,当前箭矢:{self.arrows}")
def get_status(self):
"""重写状态信息"""
base_status = super().get_status()
return f"{base_status} 箭矢:{self.arrows}/{self.max_arrows}"
# 使用游戏角色系统
warrior = Warrior("战士")
mage = Mage("法师")
archer = Archer("弓箭手")
characters = [warrior, mage, archer]
# 创建敌人
enemy = Character("怪物", 2)
print("角色状态:")
for char in characters:
print(f" {char.get_status()}")
print(f"\n敌人状态:{enemy.get_status()}")
# 战斗示例
print("\n战斗开始!")
while enemy.is_alive() and any(char.is_alive() for char in characters):
for char in characters:
if char.is_alive() and enemy.is_alive():
if isinstance(char, Warrior):
char.attack_target(enemy)
elif isinstance(char, Mage):
if random.random() < 0.3:
char.fireball(enemy)
else:
char.attack_target(enemy)
elif isinstance(char, Archer):
char.attack_target(enemy)
if enemy.is_alive():
# 敌人反击
alive_characters = [char for char in characters if char.is_alive()]
if alive_characters:
target = random.choice(alive_characters)
enemy.attack_target(target)
print("\n战斗结束!")
print("角色状态:")
for char in characters:
print(f" {char.get_status()}")
# 获得经验
for char in characters:
if char.is_alive():
char.gain_experience(50)
继承和多态的最佳实践
推荐做法:
- 使用继承表示"是一个"关系
- 合理使用super()调用父类方法
- 遵循里氏替换原则
- 使用多态提高代码灵活性
避免的做法:
- 过度使用继承
- 忽略方法重写的语义
- 创建过深的继承层次
- 在多态中违反契约
高级继承特性
多继承
class Flyable:
"""可飞行接口"""
def fly(self):
print("正在飞行")
def land(self):
print("正在降落")
class Swimmable:
"""可游泳接口"""
def swim(self):
print("正在游泳")
def dive(self):
print("正在潜水")
class Duck(Animal, Flyable, Swimmable):
"""鸭子类 - 多继承"""
def __init__(self, name):
Animal.__init__(self, name, "鸭子")
def make_sound(self):
print(f"{self.name}说:嘎嘎!")
# 使用多继承
duck = Duck("唐老鸭")
duck.make_sound()
duck.fly()
duck.swim()
duck.dive()
回顾
今天您学习了:
- 继承的基本概念和实现
- 方法重写和super()函数的使用
- 多态的概念和应用
- 真实世界示例:动物系统、图形系统、员工管理
继承和多态是面向对象编程的核心,掌握这些概念将让您能够创建更加灵活和可扩展的代码!
相关推荐
- 龙建股份:工程项目中标_龙建股份有限公司招聘网
-
404NotFoundnginx/1.6.1【公告简述】2016年9月8日公告,公司于2016年9月6日收到苏丹共和国(简称“北苏丹”)喀土穆州基础设施与运输部公路、桥梁和排水公司出具的中标通知书...
- 福田汽车:获得政府补助_福田 补贴
-
404NotFoundnginx/1.6.1【公告简述】2016年9月1日公告,自2016年8月17日至今,公司共收到产业发展补助、支持资金等与收益相关的政府补助4笔,共计5429.08万元(不含...
- 翰宇药业:获得发明专利_翰宇药业创新产业
-
404NotFoundnginx/1.6.1【公告简述】2016年9月2日公告,申请的一项发明专利获得中华人民共和国国家知识产权局颁发的发明专利证书,公司于2016年9月1日取得了该专利证书,该专...
- 川金诺:取得发明专利证书_川金诺(300505)
-
404NotFoundnginx/1.6.1【公告简述】2016年9月1日公告,近日,公司申请的一项发明专利获得国家知识产权局颁发的发明专利证书:一种提高和稳定湿法磷酸中和脱氟浓度方法。本发明是稀...
- 使用WTM框架创建博客系统后台并在云服务器发布
-
阅读导航关于lqclass.com博客后台前后端部署2.1已部署访问链接2.2nginx部署2.2.1后台后端发布2.2.2后台前端发布2.2.3云服务器部署下次分享1.关于lqcl...
- Nginx的location匹配规则,90%的人都没完全搞懂,一张图让你秒懂
-
为什么你的Nginx配置总是不生效?改了Nginx配置无数次,reload命令执行了几十遍,浏览器访问时却依然返回404?运维工程师小张上周就遇到了这个问题:明明配置了location/static...
- 全网最新的Dify(1.7.2)私有化离线部署教程(ARM架构)
-
Hello,大家好!近期工作中有涉及到Dify私有化离线部署,特别是针对于一些国产设备。因此特别整理了该教程,实测有效!有需要的小伙伴可以参考下!本文主要针对Dify1.7.2最新版本+国产操作系...
- 如何使用 Certbot 为域名配置永久免费的 HTTPS 证书
-
本文手把手教你如何在Linux上使用Certbot配置HTTPS,包括安装Certbot、修改Nginx配置、设置server_name、申请证书及证书续期。文章内容C一.安装...
- docker run 中 --name 参数介绍_docker run -itd --name
-
在Docker中,--name是dockerrun命令的一个重要参数,用于为新创建的容器指定一个唯一的自定义名称。以下是详细介绍和使用场景:一、--name的功能与语法作用:为容器分配一个...
- 403 Forbidden:无权限访问请求的资源如何处理
-
403Forbidden错误表示客户端(如浏览器或应用)已成功连接服务器,但服务器拒绝了该请求。这通常是由于用户或请求没有足够的权限访问目标资源。以下是常见的可能原因和解决方法:1.常见原因1....
- 使用docker compose实现最简单的容器伸缩、健康检查和负载均衡
-
跟K8S的自动伸缩配置类似,仅使用dockercompose也可以实现低配版的autoscale哟!本文非常的接地气,从头一步步开始,连带Dockerfile制作,容器健康检查,Nginx负载均衡...
- Nginx反向代理和正向代理详解(4大核心区别)
-
关注△mikechen△,十余年BAT架构经验倾囊相授!Nginx是大型架构的必备中间件,本篇重点详解Nginx代理@mikechen文章来源:mikechen.cc1.服务对象不同服务对象不同,这...
- docker真的好难用啊,为什么说它移植性好啊?
-
刚刚接触docker,真的好麻烦啊,不明白为什么要选择docker,我都搞了两天还在搭环境,又告诉我Windows版本过低不适配docker,转而在Ubuntu里装docker,然后MySQL、php...
- Nginx动静分离技术详解(原理+配置+案例)
-
关注△mikechen△,十余年BAT架构经验倾囊相授!Nginx是大型架构的必备技能,下面我详解Nginx动静分离技术@mikechen文章来源:mikechen.ccNginx动静分离动静分离:是...
- zabbix搭建+排错+批量监控_zabbix批量添加监控项
-
Zabbix软件的概念Zabbix是一款开源的、免费的监控软件、项目,主要是7x24小时去监控网络设备、操作系统、应用程序、带宽等资源,一旦发现异常和故障能够给SA管理员发送告警信息。Zabbix软件...
你 发表评论:
欢迎- 一周热门
- 最近发表
- 标签列表
-
- python计时 (73)
- python安装路径 (56)
- python类型转换 (93)
- python进度条 (67)
- python吧 (67)
- python的for循环 (65)
- python格式化字符串 (61)
- python静态方法 (57)
- python列表切片 (59)
- python面向对象编程 (60)
- python 代码加密 (65)
- python串口编程 (77)
- python封装 (57)
- python写入txt (66)
- python读取文件夹下所有文件 (59)
- python操作mysql数据库 (66)
- python获取列表的长度 (64)
- python接口 (63)
- python调用函数 (57)
- python多态 (60)
- python匿名函数 (59)
- python打印九九乘法表 (65)
- python赋值 (62)
- python异常 (69)
- python元祖 (57)