前端开发入门到精通的在线学习网站

网站首页 > 资源文章 正文

Python教程(二十三):继承和多态(python多继承简单案例)

qiguaw 2025-07-27 23:24:15 资源文章 4 ℃ 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()函数的使用
  • 多态的概念和应用
  • 真实世界示例:动物系统、图形系统、员工管理

继承和多态是面向对象编程的核心,掌握这些概念将让您能够创建更加灵活和可扩展的代码!

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表