AI for Youth Academy 青少年AI研究计划

第一年 · 第15周

第十五章:继承——家族树

上周你从零开始设计了自己的类。本周你将学习如何创建一个子类,它自动获得父类的所有内容——然后再添加自己的技能。这叫做继承,是编程中最强大的概念之一。

第六课时:继承——家族树

时长:60 分钟

学习目标

  • 定义一个从父类继承的子类
  • 解释子类自动获得父类的所有方法
  • 为子类添加父类没有的新方法

热身——家族特征(10分钟)

在编程中也一样:

  • 皮卡丘雷丘都是宝可梦——它们都继承了 HP、伤害值、attack 方法……
  • 雷丘拥有额外的属性和方法,小皮卡丘没有。
# 父类 = Pokemon(宝可梦)
# 子类 = ElectricPokemon(电系宝可梦)
# ElectricPokemon 自动拥有 Pokemon 的所有功能
# 但还可以拥有自己独有的能力!

构建父类——Animal(15分钟)

我们先写一个简单的 Animal 类。它有三个方法:eat()sleep()__str__()

class Animal:
    def __init__(self, name, hp):
        self.name = name
        self.hp   = hp

    def eat(self):
        self.hp += 10
        print(f'{self.name} 吃了食物。HP: {self.hp}')

    def sleep(self):
        print(f'{self.name} 正在睡觉……')

    def __str__(self):
        return f'{self.name} (HP: {self.hp})'

我们来测试一下:

cat = Animal('小猫', 50)
print(cat)       # 小猫 (HP: 50)
cat.eat()          # 小猫 吃了食物。HP: 60
cat.sleep()        # 小猫 正在睡觉……

创建子类——Dog(25分钟)

现在写一个 Dog 类,继承 Animal 的所有内容:

class Dog(Animal):   # Dog 继承自 Animal
    pass             # 里面什么都没有!

rex = Dog('Rex', 80)
print(rex)           # Rex (HP: 80)  ← 用了 Animal 的 __str__
rex.eat()              # Rex 吃了食物。HP: 90  ← 用了 Animal 的 eat()
rex.sleep()            # Rex 正在睡觉……  ← 用了 Animal 的 sleep()

添加子类独有的方法

Dog 虽然继承了所有动物都有的能力,但狗还有自己的特殊技能。我们来添加 bark()fetch()

class Dog(Animal):
    def bark(self):
        print(f'{self.name} 说:汪汪!')

    def fetch(self, item):
        print(f'{self.name} 去捡 {item}!')

rex = Dog('Rex', 80)
rex.bark()           # Rex 说:汪汪!
rex.fetch('球')      # Rex 去捡 球!
rex.eat()            # 仍然有效——从 Animal 继承的

用属性区分

如果狗还有自己独有的属性呢?我们可以在 Dog__init__ 中添加:

class Dog(Animal):
    def __init__(self, name, hp, breed):
        super().__init__(name, hp)   # 调用 Animal 的 __init__
        self.breed = breed               # Dog 独有的属性

    def bark(self):
        print(f'{self.name}({self.breed})说:汪汪!')

    def fetch(self, item):
        print(f'{self.name} 去捡 {item}!')

rex = Dog('Rex', 80, '金毛')
rex.bark()      # Rex(金毛)说:汪汪!
rex.eat()        # Rex 吃了食物。HP: 90  ← 继承自 Animal

搭档练习(10分钟)

按照上面的模式,添加第二个子类 Cat(Animal)。要求:

  1. Cat 继承自 Animal
  2. 添加一个 purr() 方法——打印"___ 正在呼噜呼噜……"
  3. 添加一个 scratch(target) 方法——让 target 的 HP 减少 5
  4. 创建一个 Dog 和一个 Cat,让它们互动(比如狗叫、猫抓)
显示参考答案
class Cat(Animal):
    def purr(self):
        print(f'{self.name} 正在呼噜呼噜……')

    def scratch(self, target):
        target.hp -= 5
        print(f'{self.name} 抓了 {target.name}!HP -5')

# 创建一个狗和一个猫
rex = Dog('Rex', 80)
whiskers = Cat('Whiskers', 40)

rex.bark()              # Rex 说:汪汪!
whiskers.scratch(rex)     # Whiskers 抓了 Rex!HP -5
print(rex)                # Rex (HP: 75)
whiskers.purr()            # Whiskers 正在呼噜呼噜……
whiskers.eat()              # Whiskers 吃了食物。HP: 50  ← 继承自 Animal

画继承树

在纸上画出我们今天创建的继承关系:

  1. 在纸的顶部写上 Animal,列出它的方法:__init__eatsleep__str__
  2. 在下面画两个框:DogCat
  3. Animal 画箭头向下到 DogCat
  4. Dog 框里写上它独有的方法:barkfetch
  5. Cat 框里写上它独有的方法:purrscratch
  6. 用不同颜色标出哪些方法是继承的,哪些是独有

出口票

  1. class Dog(Animal): 是什么意思?用你自己的话解释。
  2. 如果 Animal 有 3 个方法,Dog 又添加了 2 个新方法,一个 Dog 对象一共有多少个方法?
  3. 一个普通的 Animal 对象能调用 bark() 吗?为什么?

关键词汇