第一年 · 第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)。要求:
Cat继承自Animal- 添加一个
purr()方法——打印"___ 正在呼噜呼噜……" - 添加一个
scratch(target)方法——让target的 HP 减少 5 - 创建一个
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
画继承树
在纸上画出我们今天创建的继承关系:
- 在纸的顶部写上
Animal,列出它的方法:__init__、eat、sleep、__str__ - 在下面画两个框:
Dog和Cat - 从
Animal画箭头向下到Dog和Cat - 在
Dog框里写上它独有的方法:bark、fetch - 在
Cat框里写上它独有的方法:purr、scratch - 用不同颜色标出哪些方法是继承的,哪些是独有的
出口票
class Dog(Animal):是什么意思?用你自己的话解释。- 如果
Animal有 3 个方法,Dog又添加了 2 个新方法,一个Dog对象一共有多少个方法? - 一个普通的
Animal对象能调用bark()吗?为什么?