作者: 中文编程倡导者------ 李金雨
联系方式: wbtm2718@qq.com
系列: python中文编程入门教程** 核心理念: AI时代必须使用中文编程,母语编程阅读效率极高"
第10篇:继承扩展------面向对象编程进阶
开篇引入
本课目标
- 理解什么是继承扩展(继承)
- 掌握如何定义子模板(子类)
- 学会子模板使用父模板的成员
- 掌握如何重写父模板的功能
- 学会在子模板中扩展新功能
- 理解super()功能的使用
生活场景引入
同学们,在日常生活中,我们经常会遇到继承的概念:
- 儿子继承父亲的特征,又有自己的特点
- 智能手机是手机的一种,具有手机的基本功能,又有自己的特殊功能
- 狗和猫都是动物,具有动物的共同特征,又有自己的独特特征
在Python中,继承是面向对象编程的重要概念,它允许我们基于已有类创建新类,重用已有代码,同时添加新的功能。通过继承,我们可以构建更加灵活和可维护的代码结构。
预期成果展示
在本课结束时,你将能够:
- 理解继承的概念和好处
- 定义子类并继承父类
- 访问和使用父类的属性和方法
- 重写父类的方法
- 在子类中添加新的属性和方法
- 使用super()函数调用父类的方法
- 编写一个继承体系,如动物-狗/猫、手机-智能手机等
概念讲解
1. 什么是继承扩展(继承)
继承是一种面向对象编程的特性,它允许一个类(子类)继承另一个类(父类)的属性和方法。
父模板和子模板:
- 父类(基类):被继承的类,提供基本的属性和方法
- 子类(派生类):继承父类的类,可以添加新的属性和方法,或重写父类的方法
为什么要继承:
- 代码复用:避免重复编写相同的代码
- 扩展功能:在现有功能的基础上添加新功能
- 建立层次结构:更好地组织代码,反映现实世界的关系
继承的好处:
- 减少代码冗余
- 提高代码可维护性
- 增强代码的可扩展性
- 建立清晰的代码层次结构
生活例子:
- 继承就像儿子继承父亲的特征,又有自己的特点
- 就像"手机"是父类,"智能手机"是子类
- 就像"动物"是父类,"狗"、"猫"是子类
2. 定义子模板
在Python中,定义子类的语法如下:
python
class 子类名(父类名):
# 子类的属性和方法
继承的语法:
- 子类名后面跟着括号,括号中是父类名
- 子类继承父类的所有属性和方法
- 子类可以添加自己的属性和方法
代码示例:
python
# 父类:动物
class 动物:
"""动物模板"""
def __init__(self, 名称, 年龄):
"""初始构造功能"""
self.名称 = 名称
self.年龄 = 年龄
def 吃(self):
"""动物吃饭"""
print(f"{self.名称}在吃饭")
def 睡(self):
"""动物睡觉"""
print(f"{self.名称}在睡觉")
# 子类:狗(继承自动物)
class 狗(动物):
"""狗模板"""
def __init__(self, 名称, 年龄, 品种):
"""初始构造功能"""
# 调用父类的构造函数
super().__init__(名称, 年龄)
# 添加子类特有的属性
self.品种 = 品种
def 叫(self):
"""狗叫"""
print(f"{self.名称}在汪汪叫")
# 子类:猫(继承自动物)
class 猫(动物):
"""猫模板"""
def __init__(self, 名称, 年龄, 颜色):
"""初始构造功能"""
# 调用父类的构造函数
super().__init__(名称, 年龄)
# 添加子类特有的属性
self.颜色 = 颜色
def 叫(self):
"""猫叫"""
print(f"{self.名称}在喵喵叫")
3. 子模板使用父模板的成员
子类继承了父类的所有属性和方法,可以直接使用它们。
继承成员数据:
- 子类可以访问和修改从父类继承的属性
- 子类可以添加自己的属性
继承成员功能:
- 子类可以调用从父类继承的方法
- 子类可以重写父类的方法
代码示例:
python
# 创建狗实例
狗1 = 狗("旺财", 3, "金毛")
# 调用从父类继承的方法
狗1.吃()
狗1.睡()
# 调用子类自己的方法
狗1.叫()
# 访问从父类继承的属性
print(f"狗的名称:{狗1.名称}")
print(f"狗的年龄:{狗1.年龄}岁")
# 访问子类自己的属性
print(f"狗的品种:{狗1.品种}")
# 创建猫实例
猫1 = 猫("小白", 2, "白色")
# 调用从父类继承的方法
猫1.吃()
猫1.睡()
# 调用子类自己的方法
猫1.叫()
# 访问从父类继承的属性
print(f"猫的名称:{猫1.名称}")
print(f"猫的年龄:{猫1.年龄}岁")
# 访问子类自己的属性
print(f"猫的颜色:{猫1.颜色}")
4. 重写父模板的功能
重写是指子类重新实现父类的方法,以满足子类的特定需求。
什么是重写:
- 子类定义与父类同名的方法
- 子类的方法会覆盖父类的方法
- 重写时,方法签名(方法名和参数)通常与父类相同
如何重写:
- 在子类中定义与父类同名的方法
- 在方法中实现子类特有的逻辑
- 可以使用super()函数调用父类的方法
代码示例:
python
# 父类:手机
class 手机:
"""手机模板"""
def __init__(self, 品牌, 型号):
"""初始构造功能"""
self.品牌 = 品牌
self.型号 = 型号
def 打电话(self, 号码):
"""打电话"""
print(f"使用{self.品牌}{self.型号}给{号码}打电话")
def 发短信(self, 号码, 内容):
"""发短信"""
print(f"使用{self.品牌}{self.型号}给{号码}发短信:{内容}")
# 子类:智能手机(继承自手机)
class 智能手机(手机):
"""智能手机模板"""
def __init__(self, 品牌, 型号, 系统):
"""初始构造功能"""
super().__init__(品牌, 型号)
self.系统 = 系统
# 重写打电话方法
def 打电话(self, 号码):
"""打电话(重写)"""
print(f"使用{self.品牌}{self.型号}({self.系统}系统)给{号码}打电话")
# 添加新方法
def 上网(self):
"""上网"""
print(f"使用{self.品牌}{self.型号}({self.系统}系统)上网")
def 安装应用(self, 应用名称):
"""安装应用"""
print(f"在{self.品牌}{self.型号}({self.系统}系统)上安装{应用名称}")
# 创建智能手机实例
手机1 = 智能手机("苹果", "iPhone 13", "iOS")
# 调用重写的方法
手机1.打电话("13812345678")
# 调用从父类继承的方法
手机1.发短信("13812345678", "你好")
# 调用子类自己的方法
手机1.上网()
手机1.安装应用("微信")
5. 扩展新功能
子类可以在继承父类的基础上,添加新的属性和方法,扩展父类的功能。
子模板添加新成员:
- 子类可以添加自己特有的属性
- 子类可以添加自己特有的方法
子模板添加新功能:
- 新功能可以是父类没有的功能
- 新功能可以是对父类功能的扩展
代码示例:
python
# 父类:学生
class 学生:
"""学生模板"""
def __init__(self, 姓名, 年龄):
"""初始构造功能"""
self.姓名 = 姓名
self.年龄 = 年龄
self.学校 = "某某中学"
def 学习(self):
"""学习"""
print(f"{self.姓名}在学习")
def 显示信息(self):
"""显示信息"""
print(f"姓名:{self.姓名},年龄:{self.年龄}")
# 子模板:高中生(继承学生)
class 高中生(学生):
def __init__(self, 姓名, 年龄, 文理科):
# 调用父模板的构造函数
super().__init__(姓名, 年龄)
self.文理科 = 文理科 # 新成员
self.高考分数 = 0 # 新成员
def 备考(self):
"""高中生特有的功能"""
print(f"{self.姓名}正在备考高考")
def 参加高考(self, 分数):
"""参加高考"""
self.高考分数 = 分数
print(f"{self.姓名}高考考了{分数}分")
def 显示信息(self):
"""重写父模板的功能"""
super().显示信息() # 调用父模板的功能
print(f"文理科:{self.文理科},高考分数:{self.高考分数}")
# 创建实例
高中生一 = 高中生("王五", 17, "理科")
高中生一.学习() # 继承的功能
高中生一.备考() # 自己的功能
高中生一.参加高考(680)
高中生一.显示信息()
6. super()功能
super()函数用于调用父类的方法,在子类中使用。
调用父模板的构造函数:
- 在子类的
__init__方法中使用super().__init__()调用父类的构造函数 - 确保父类的属性被正确初始化
调用父模板的其他功能:
- 在子类的方法中使用
super().方法名()调用父类的方法 - 可以在调用父类方法的基础上添加子类特有的逻辑
代码示例:
python
# 父类:动物
class 动物:
"""动物模板"""
def __init__(self, 名称, 年龄):
"""初始构造功能"""
self.名称 = 名称
self.年龄 = 年龄
def 吃(self):
"""动物吃饭"""
print(f"{self.名称}在吃饭")
# 子类:狗(继承自动物)
class 狗(动物):
"""狗模板"""
def __init__(self, 名称, 年龄, 品种):
"""初始构造功能"""
# 调用父类的构造函数
super().__init__(名称, 年龄)
# 添加子类特有的属性
self.品种 = 品种
def 吃(self):
"""狗吃饭(重写)"""
# 调用父类的吃方法
super().吃()
# 添加子类特有的逻辑
print(f"{self.名称}({self.品种})喜欢吃肉")
# 创建狗实例
狗1 = 狗("旺财", 3, "金毛")
狗1.吃()
动手实践
基础练习(必做)
-
创建大学生模板 :编写一个大学生类,继承学生类,添加专业和学分
python# 学生类(父类) class 学生: """学生模板""" def __init__(self, 姓名, 年龄): """初始构造功能""" self.姓名 = 姓名 self.年龄 = 年龄 def 学习(self): """学习""" print(f"{self.姓名}在学习") def 显示信息(self): """显示信息""" print(f"姓名:{self.姓名},年龄:{self.年龄}岁") # 大学生类(子类) class 大学生(学生): """大学生模板""" def __init__(self, 姓名, 年龄, 专业, 学分=0): """初始构造功能""" # 调用父类的构造函数 super().__init__(姓名, 年龄) # 添加子类特有的属性 self.专业 = 专业 self.学分 = 学分 def 选课(self, 课程, 学分): """选课""" self.学分 += 学分 print(f"{self.姓名}选了{课程},获得{学分}学分") def 显示信息(self): """显示信息""" # 调用父类的显示信息方法 super().显示信息() # 添加子类特有的信息 print(f"专业:{self.专业},学分:{self.学分}") # 测试大学生类 大学生1 = 大学生("张三", 20, "计算机科学与技术") 大学生1.学习() 大学生1.选课("Python编程", 3) 大学生1.选课("数据结构", 4) 大学生1.显示信息() -
创建智能手机模板 :编写一个智能手机类,继承手机类,添加智能功能
python# 手机类(父类) class 手机: """手机模板""" def __init__(self, 品牌, 型号): """初始构造功能""" self.品牌 = 品牌 self.型号 = 型号 def 打电话(self, 号码): """打电话""" print(f"使用{self.品牌}{self.型号}给{号码}打电话") def 发短信(self, 号码, 内容): """发短信""" print(f"使用{self.品牌}{self.型号}给{号码}发短信:{内容}") # 智能手机类(子类) class 智能手机(手机): """智能手机模板""" def __init__(self, 品牌, 型号, 系统, 存储=64): """初始构造功能""" # 调用父类的构造函数 super().__init__(品牌, 型号) # 添加子类特有的属性 self.系统 = 系统 self.存储 = 存储 self.应用列表 = [] def 打电话(self, 号码): """打电话(重写)""" print(f"使用{self.品牌}{self.型号}({self.系统}系统)给{号码}打电话") def 上网(self): """上网""" print(f"使用{self.品牌}{self.型号}({self.系统}系统)上网") def 安装应用(self, 应用名称): """安装应用""" self.应用列表.append(应用名称) print(f"在{self.品牌}{self.型号}({self.系统}系统)上安装{应用名称}") def 显示信息(self): """显示信息""" print(f"品牌:{self.品牌}") print(f"型号:{self.型号}") print(f"系统:{self.系统}") print(f"存储:{self.存储}GB") print(f"已安装应用:{self.应用列表}") # 测试智能手机类 手机1 = 智能手机("苹果", "iPhone 13", "iOS", 128) 手机1.打电话("13812345678") 手机1.发短信("13812345678", "你好") 手机1.上网() 手机1.安装应用("微信") 手机1.安装应用("支付宝") 手机1.显示信息()
进阶练习(选做)
-
创建电动车模板 :编写一个电动车类,继承汽车类,添加电池相关功能
python# 汽车类(父类) class 汽车: """汽车模板""" def __init__(self, 品牌, 型号, 颜色): """初始构造功能""" self.品牌 = 品牌 self.型号 = 型号 self.颜色 = 颜色 self.速度 = 0 def 加速(self, 增加速度): """加速""" self.速度 += 增加速度 print(f"{self.颜色}的{self.品牌}{self.型号}加速到{self.速度} km/h") def 减速(self, 减少速度): """减速""" self.速度 = max(0, self.速度 - 减少速度) print(f"{self.颜色}的{self.品牌}{self.型号}减速到{self.速度} km/h") # 电动车类(子类) class 电动车(汽车): """电动车模板""" def __init__(self, 品牌, 型号, 颜色, 电池容量=40): """初始构造功能""" # 调用父类的构造函数 super().__init__(品牌, 型号, 颜色) # 添加子类特有的属性 self.电池容量 = 电池容量 self.剩余电量 = 100 def 充电(self, 电量): """充电""" self.剩余电量 = min(100, self.剩余电量 + 电量) print(f"{self.颜色}的{self.品牌}{self.型号}充电到{self.剩余电量}%") def 加速(self, 增加速度): """加速(重写)""" if self.剩余电量 > 10: super().加速(增加速度) self.剩余电量 -= 5 print(f"剩余电量:{self.剩余电量}%") else: print("电量不足,请充电") def 显示信息(self): """显示信息""" print(f"品牌:{self.品牌}") print(f"型号:{self.型号}") print(f"颜色:{self.颜色}") print(f"当前速度:{self.速度} km/h") print(f"电池容量:{self.电池容量} kWh") print(f"剩余电量:{self.剩余电量}%") # 测试电动车类 电动车1 = 电动车("特斯拉", "Model 3", "红色", 75) 电动车1.加速(60) 电动车1.加速(30) 电动车1.减速(20) 电动车1.充电(50) 电动车1.显示信息() -
创建动物继承体系 :编写一个动物继承体系,包括动物、哺乳动物、鸟类等
python# 动物类(父类) class 动物: """动物模板""" def __init__(self, 名称, 年龄): """初始构造功能""" self.名称 = 名称 self.年龄 = 年龄 def 吃(self): """动物吃饭""" print(f"{self.名称}在吃饭") def 睡(self): """动物睡觉""" print(f"{self.名称}在睡觉") # 哺乳动物类(子类) class 哺乳动物(动物): """哺乳动物模板""" def __init__(self, 名称, 年龄, 胎生=True): """初始构造功能""" super().__init__(名称, 年龄) self.胎生 = 胎生 def 哺乳(self): """哺乳""" print(f"{self.名称}在哺乳") # 鸟类(子类) class 鸟类(动物): """鸟类模板""" def __init__(self, 名称, 年龄, 会飞=True): """初始构造功能""" super().__init__(名称, 年龄) self.会飞 = 会飞 def 飞(self): """飞""" if self.会飞: print(f"{self.名称}在飞翔") else: print(f"{self.名称}不会飞") # 狗类(继承自哺乳动物) class 狗(哺乳动物): """狗模板""" def __init__(self, 名称, 年龄, 品种): """初始构造功能""" super().__init__(名称, 年龄) self.品种 = 品种 def 叫(self): """狗叫""" print(f"{self.名称}在汪汪叫") # 鹦鹉类(继承自鸟类) class 鹦鹉(鸟类): """鹦鹉模板""" def __init__(self, 名称, 年龄, 颜色): """初始构造功能""" super().__init__(名称, 年龄) self.颜色 = 颜色 def 说话(self): """说话""" print(f"{self.名称}在说话") # 测试动物继承体系 狗1 = 狗("旺财", 3, "金毛") 狗1.吃() 狗1.睡() 狗1.哺乳() 狗1.叫() 鹦鹉1 = 鹦鹉("波利", 2, "绿色") 鹦鹉1.吃() 鹦鹉1.睡() 鹦鹉1.飞() 鹦鹉1.说话()
挑战练习(拓展)
-
创建图形继承体系 :编写一个图形继承体系,包括图形、圆形、矩形、三角形等
python# 图形类(父类) class 图形: """图形模板""" def __init__(self, 名称): """初始构造功能""" self.名称 = 名称 def 计算面积(self): """计算面积""" pass def 计算周长(self): """计算周长""" pass def 显示信息(self): """显示信息""" print(f"图形名称:{self.名称}") print(f"面积:{self.计算面积()}") print(f"周长:{self.计算周长()}") # 圆形类(子类) class 圆形(图形): """圆形模板""" def __init__(self, 半径): """初始构造功能""" super().__init__("圆形") self.半径 = 半径 def 计算面积(self): """计算面积""" import math return math.pi * self.半径 ** 2 def 计算周长(self): """计算周长""" import math return 2 * math.pi * self.半径 def 显示信息(self): """显示信息""" super().显示信息() print(f"半径:{self.半径}") # 矩形类(子类) class 矩形(图形): """矩形模板""" def __init__(self, 长, 宽): """初始构造功能""" super().__init__("矩形") self.长 = 长 self.宽 = 宽 def 计算面积(self): """计算面积""" return self.长 * self.宽 def 计算周长(self): """计算周长""" return 2 * (self.长 + self.宽) def 显示信息(self): """显示信息""" super().显示信息() print(f"长:{self.长},宽:{self.宽}") # 三角形类(子类) class 三角形(图形): """三角形模板""" def __init__(self, a, b, c): """初始构造功能""" super().__init__("三角形") self.a = a self.b = b self.c = c def 计算面积(self): """计算面积(海伦公式)""" s = (self.a + self.b + self.c) / 2 return (s * (s - self.a) * (s - self.b) * (s - self.c)) ** 0.5 def 计算周长(self): """计算周长""" return self.a + self.b + self.c def 显示信息(self): """显示信息""" super().显示信息() print(f"三边:{self.a}, {self.b}, {self.c}") # 测试图形继承体系 圆形1 = 圆形(5) 圆形1.显示信息() print("\n") 矩形1 = 矩形(10, 5) 矩形1.显示信息() print("\n") 三角形1 = 三角形(3, 4, 5) 三角形1.显示信息()
知识总结
核心概念回顾
- 继承:子类继承父类的属性和方法
- 父类:被继承的类,提供基本功能
- 子类:继承父类的类,可以添加或重写功能
- 重写:子类重新实现父类的方法
- super():调用父类的方法
关键代码速查
| 功能 | 代码 | 说明 |
|---|---|---|
| 定义子类 | class 子类名(父类名): |
定义一个继承自父类的子类 |
| 调用父类构造函数 | super().__init__(参数) |
在子类构造函数中调用父类构造函数 |
| 重写方法 | def 方法名(self, 参数): |
在子类中重新实现父类的方法 |
| 调用父类方法 | super().方法名(参数) |
在子类方法中调用父类的方法 |
| 添加新属性 | self.新属性 = 值 |
在子类中添加新的属性 |
| 添加新方法 | def 新方法(self, 参数): |
在子类中添加新的方法 |
常见错误提醒
- 忘记调用父类构造函数 :子类构造函数中没有调用
super().__init__() - 方法签名不匹配:重写方法时参数与父类不一致
- 循环继承:两个类相互继承
- 属性访问错误:访问不存在的属性
- super()使用错误:在非方法中使用super()
课后作业
巩固练习题
- 编写一个教师类,继承人员类,添加学科和教龄
- 编写一个图书类,继承出版物类,添加作者和ISBN
创意编程题
- 编写一个公司员工继承体系,包括员工、经理、普通员工等
- 编写一个电子设备继承体系,包括电子设备、电脑、手机、平板等
下篇预习提示
在下一篇中,我们将学习代码文件组织,了解如何将代码组织到多个文件中。请思考:
- 如何将相关的代码组织到一个模块中?
- 如何在一个模块中导入另一个模块?
- 如何创建和使用包?
学习交流
如果你在学习过程中遇到任何问题,欢迎联系我:
- ** 视频号,"时空系"
- 邮箱: wbtm2718@qq.com
- 其他提示:
- 本人正在开发纯中文编程语言和编译器,有兴趣的可以交流
- 本人正在写一本基于中国母语思维习惯的数学教材,可以让你一年内学完从初中到研究生的数学,而且可以让你快速掌握人工智能的关键数学知识,有兴趣的可以交流
祝你学习愉快!