面向对象高级-继承与重写

面向对象高级-继承与重写

2026年9月20日·#编程学习/python学习笔记Python/面向对象·1253 字 6 分钟
浏览量加载中...
AI 摘要

继承的语法与"只继承非私有"的规则、方法重写的两种调用父类方式,以及多继承与 MRO 解析顺序

继承是什么#

继承描述的是两个类之间的关系:子类继承父类,就可以获取到父类中的属性和方法。

为什么要用它?看这个例子:燃油车和电车都需要”启动、停止、行驶”,如果各写一遍就是重复代码。把公共部分抽出来做成 Car(父类),两种车继承它即可:

class Car:
def __init__(self, brand, model, color):
self.brand = brand
self.model = model
self.color = color
def start(self):
print(f'{self.brand} {self.model} 正在启动...')
def stop(self):
print(f'{self.brand} {self.model} 停止行驶...')
def run(self):
print(f'{self.brand} {self.model} 正在行驶...')
class FuelCar(Car): # 子类(父类):括号里写父类的类名
pass
class ElectricCar(Car):
pass
c1 = FuelCar("BMW", "X5", "黑色") # 子类不需要自己写 __init__,直接用父类的
c1.start() # BMW X5 正在启动...
c1.run() # BMW X5 正在行驶...
Important

子类会把父类**公共的(非私有)**属性和方法继承下来,私有的继承不到。所以父类里 self.__owner 这类私有属性,子类无法直接使用(可以先调父类的 get_owner() 取脱敏值)。

方法重写#

重写是指子类继承父类后,如果父类中的方法不满足需求,可以在子类中重新定义一个同名方法,从而用子类的实现替换父类的实现。

class Car:
def charge(self):
print(f'{self.brand} {self.model} 正在补充燃料...')
class FuelCar(Car):
def charge(self):
Car.charge(self) # 方式二:父类名.方法名(self)
print(f'{self.brand} {self.model} 正在加油...')
class ElectricCar(Car):
def charge(self):
super().charge() # 方式一:super().方法名()
print(f'{self.brand} {self.model} 正在充电...')
问题答案
什么是重写?在子类中重新定义与父类同名的方法,用子类自己的实现替换父类的实现
如何在子类里调用父类的方法?方式一 super().方法名();方式二 父类名.方法名(self)

多继承与 MRO#

多继承指的是一个子类同时继承多个父类(会把多个父类中非私有的属性和方法都继承下来)。

class XiaomiAiDriving: # 智驾系统
def __init__(self, version="V1.0"):
self.version = version
def run(self):
print(f'使用智驾系统{self.version}正在行驶...')
class SmartCar(Car, XiaomiAiDriving): # 同时继承两个父类
def __init__(self, brand, model, color, version="V1.0"):
Car.__init__(self, brand, model, color)
XiaomiAiDriving.__init__(self, version)
def run(self):
Car.run(self) # 两个父类的 run 都想用,就都显式调用
XiaomiAiDriving.run(self)
Note

MRO:Method Resolution Order(方法解析顺序)。当一个类继承了多个父类时,默认优先使用第一个父类中的同名属性或方法;查看顺序可以用 类名.__mro__ 属性或 类名.mro() 方法。

相关#

练习题#

一、回忆填空(写完再展开对答案)#

  1. 继承描述的是两个类之间的关系:子类继承父类,就能获取父类的 ____ 和 ____
  2. 继承的语法:class 子类(____):
  3. 子类能继承父类____(全部 / 只有非私有)的属性和方法
  4. 重写是指在子类中重新定义与父类 ____ 的方法,用子类的实现替换父类
  5. 在子类里调用父类方法有两种写法:____().方法名()____.方法名(self)
  6. 多继承的语法:class 子类(父类1, 父类2):;同名方法默认优先使用第 ____ 个父类的
  7. 查看方法解析顺序用 类名.____ 属性或 类名.____() 方法,缩写是 ____
填空答案(做完再点开)
  1. 属性 / 方法 2. 父类 3. 只有非私有 4. 同名 5. super / 父类名 6. 一 7. __mro__ / mro / MRO(Method Resolution Order,方法解析顺序)

二、裸写题#

  • 2-1 抽出父类 定义 Animal 父类(属性 name、方法 speak()),再定义 DogCat 两个子类继承它,实例化后分别调用 speak()

    提示(先自己想,实在想不出再点开)

    一级 · 思路:公共的属性/方法放父类,子类只写 class 子类(父类): pass 二级 · 方法class Dog(Animal): 三级 · 骨架:子类不用写 __init__,直接用父类的

  • 2-2 重写方法DogCat 各自重写 speak():狗输出”汪汪”,猫输出”喵喵”;并在子类里先用 super() 调用一次父类的 speak()

    提示

    一级 · 思路:写一个和父类同名的方法即可覆盖 二级 · 方法super().speak() 三级 · 骨架:先 super().speak() 再打印子类特有的声音

  • 2-3 多继承与 MRO 再定义一个 GuideDog(导盲犬)同时继承 Dog 和一个 Trained 类(有 guide() 方法),打印它的 MRO 看看顺序。

    提示

    一级 · 思路:多继承把两个父类的本事合到一个子类;用 MRO 确认同名方法用谁的 二级 · 方法class GuideDog(Dog, Trained): / GuideDog.__mro__ 三级 · 骨架for c in GuideDog.__mro__: print(c.__name__)

参考答案(做完再点开)
class Animal:
def __init__(self, name):
self.name = name
def speak(self):
print(f'{self.name} 发出声音...')
class Dog(Animal):
def speak(self):
super().speak() # 2-2:先调父类实现
print(f'{self.name}: 汪汪!')
class Cat(Animal):
def speak(self):
super().speak()
print(f'{self.name}: 喵喵~')
class Trained:
def guide(self):
print("正在引导主人过马路...")
class GuideDog(Dog, Trained): # 2-3:多继承
pass
d = Dog("旺财")
c = Cat("咪咪")
d.speak()
c.speak()
g = GuideDog("豆豆")
g.speak() # 用 Dog 的 speak
g.guide() # 用 Trained 的 guide
for cls in GuideDog.__mro__:
print(cls.__name__) # GuideDog → Dog → Animal → Trained → object

评论区

[ 标签 ]
# AI37# AI 编程2# AI工具1# Ajax2# Apifox1# AstrBot3# Astro2# CC Switch1# CDN2# Claude Code1# claudecode2# ClaudeCode1# Cloudflare2# CloudFlare2# CloudFlare-ImgBed3# coc3# CSS6# DeepSeek6# deepseek2# DELETE1# Docker1# EdgeOne3# Gist1# git1# GitHub1# hexo-circle-of-friends1# HTML6# HTTP5# ImageManager1# Java23# java13# JavaScript5# JDBC3# JSON2# JUnit1# LangChain25# Logback1# Maven6# Muse Spark1# Mybatis1# MyBatis4# MySQL28# MySql1# NapCat1# Node.js1# obsidian2# Obsidian5# OpenCode4# ORM1# PathVariable1# PicGo1# PyCharm1# Python65# RequestBody1# RequestMapping1# RESTful风格1# skills1# Slf4j1# SpringBoot11# SQL2# Streamlit5# Svelte2# TailwindCSS1# Telegram3# Tlias2# Vercel1# vscode2# Vue7# Waline3# WebDAV1# Web基础6# Web开发6# WinSCP1# YAML1# 三层架构1# 中二宣言1# 书籍1# 使用文档10# 写作1# 函数2# 刷步数1# 前端32# 动态1# 动漫1# 包1# 单词2# 博客7# 博客工作流1# 博客开发2# 参数接收1# 友链1# 反思2# 图床6# 地图1# 备份2# 大模型1# 奇思妙想1# 存储1# 学习方法6# 学校1# 宝塔面板3# 宝宝10# 对象1# 导航栏1# 工具2# 开发1# 开发工具1# 开发规范1# 开心1# 异常处理1# 影视2# 微信1# 性能优化2# 总结1# 想法15# 感受1# 感悟11# 指南1# 提示词工程1# 插件5# 故障排除1# 效率工具2# 教程10# 数据分析9# 数据库27# 数据结构1# 文件操作2# 斩神1# 日常92# 日志框架1# 朋友圈1# 朱元璋1# 模块1# 模板1# 正则表达式2# 测试1# 游戏2# 爬虫7# 生活迁移1# 电影2# 电脑1# 碎碎念1# 视觉识别1# 类1# 类型注解1# 网络基础2# 网络教室1# 羊毛2# 脚本2# 脚本工具1# 自动化2# 蓝奏云1# 订阅推荐2# 记录2# 评论系统1# 词根1# 词缀1# 说说1# 足迹1# 跑步2# 路径参数1# 转载2# 运动1# 部落冲突1# 配置1# 随机图1# 面向对象5# 音乐3# 音标1# 饮食1# 驼峰命名1# 高德地图1
[ 公告 ]

如果你喜欢,那么欢迎来到我的世界!

了解更多
[ 音乐 ]
封面

音乐

暂未播放

0:000:00
暂无歌词
找不到相关结果。
[ contents ]
[ 全部文章 ]