Python基础语法练习题(70)

紧接着是下面一题。

第七十题:子类重写父类方法

1. 原始版本:儿子借老爹的本事,再自己改口

#定义一个父类Vehicle,包含一个方法describe,用于描述车辆具体信息。

#定义一个子类Car,继承自vehicle,并重写describe方法,以提供关于汽车的特定信息

#定义父类

class Vehicle:

"""

定义一个父类Vehicle,包含一个方法describe,用于描述车辆具体信息。

"""

#初始化车辆对象

def init(self,make,model):

self.make = make

self.model = model

#描述车辆信息

def describe(self):

return f"这辆车的制造商是 {self.make},型号是 {self.model}。"

#定义子类,继承自父类

class Car(Vehicle):

"""

定义一个子类Car,继承自vehicle,并重写describe方法,以提供关于汽车的特定信息

"""

def init(self, make, model, year):

#调用父类的__init__,初始化制造商与型号

super().init(make, model)

#再初始化子类特有的属性

self.year = year

#重写父类方法

def describe(self):

"""

重写父类方法,提供关于汽车的特定信息

return: str

"""

return f"这辆车的年份是 {self.year}。"

#示例使用

car = Car("丰田", "卡罗拉", 2024)

#描述汽车基本信息

print(car.describe())

#调用父类的describe,展示制造商与型号信息

print(Vehicle.describe(car))

思路 :这题第一次把类串成了父子关系。父类 Vehicle 存 make 和 model,describe 把它们描述出来。子类 Car 写个 class Car(Vehicle),就白捡了老爹的全部家当------这就是继承。

子类比父类多了个 year,但 make、model 没必要重写一遍。所以在子类的 __init__ 里先 super().__init__(make, model) 把这两个交给老爹初始化,自己只管多出来的 year。能继承就别重复造轮子。

重写就是子类重新定义同名方法,把 describe 换成汽车专属的。最后印两次:car.describe() 走子类重写版,Vehicle.describe(car) 显式点名要父类版本。同一个对象,两个 describe 各说各话,继承关系一下就落地了。

局限 :只造一辆车、数据写死;而且子类 describe 只说了年份,把制造商和型号丢了,重写反而越写越窄。

2. 优化版:先选类别,再挑车,查完还能接着查

#定义一个父类Vehicle,包含一个方法describe,用于描述车辆具体信息。

#定义一个子类Car,继承自Vehicle,并重写describe方法,以提供关于汽车的特定信息。

#(优化版:两级选择------先选车辆类别,再选具体车辆查询,查完询问是否再次查询或退出)

#定义父类

class Vehicle:

"""

定义一个父类Vehicle,包含一个方法describe,用于描述车辆具体信息。

"""

#初始化车辆对象

def init(self, make, model):

self.make = make

self.model = model

#描述车辆信息

def describe(self):

return f"这辆车的制造商是 {self.make},型号是 {self.model}。"

#定义子类,继承自父类

class Car(Vehicle):

"""

定义一个子类Car,继承自Vehicle,并重写describe方法,以提供关于汽车的特定信息。

"""

def init(self, make, model, year):

#调用父类的__init__,初始化制造商与型号

super().init(make, model)

#再初始化子类特有的属性

self.year = year

#重写父类方法

def describe(self):

"""

重写父类方法,提供关于汽车的特定信息。

:return: str

"""

return f"这是一辆 {self.year} 年产的 {self.make} {self.model}。"

#按类别组织可查询的车辆:键是类别名,值是该类别下的车辆对象列表

#目前子类只有 Car(汽车),因此只提供"汽车"这一类别

vehicle_types = {

"汽车": [

Car("丰田", "卡罗拉", 2024),

Car("比亚迪", "汉", 2023),

Car("特斯拉", "Model 3", 2025),

],

}

#辅助函数:读取一个范围内的整数编号(带输入校验,两级菜单复用)

def read_index(prompt, count) -> int:

"""

反复提示用户输入,直到选择一个 1 ~ count 范围内的合法编号为止。

:param prompt: 输入提示信息

:param count: 可选择的数量上限

:return: 对应的列表索引(int)

"""

index = 0

valid = False

#使用标志位控制循环,循环外统一 return,避免 PyCharm 将 while True 误判为可能返回 None

while not valid:

try:

choice = int(input(prompt))

except ValueError:

print("输入无效,请输入一个数字。")

continue

#范围校验独立于 try/except,避免合法数字绕过边界判断

if 1 <= choice <= count:

index = choice - 1

valid = True

else:

print(f"输入超出范围,请输入 1 ~ {count} 之间的数字。")

return index

#辅助函数:展示某类别下的车辆列表

def show_vehicles(vehicles):

"""

打印该类别下所有车辆的编号与基本信息。

:param vehicles: 车辆对象列表

"""

for i, vehicle in enumerate(vehicles, start=1):

#子类汽车额外显示年份

print(f" {i}. {vehicle.make} {vehicle.model}({vehicle.year} 年)")

#主程序

while True:

#第一级:展示可查询的车辆类别,让用户先选择类别

type_names = list(vehicle_types.keys())

print("\n" + "=" * 40)

print("欢迎使用车辆信息查询系统,请选择要查询的车辆类别:")

print("=" * 40)

for i, name in enumerate(type_names, start=1):

count = len(vehicle_typesname)

print(f" {i}. {name}(可查询 {count} 辆)")

print("-" * 40)

type_index = read_index("请输入类别编号:", len(type_names))

selected_type = type_namestype_index

vehicles = vehicle_typesselected_type

#第二级:进入所选类别,展示该类别下的车辆并选择一辆查询

print(f"\n【{selected_type}】现有以下车辆可查询:")

show_vehicles(vehicles)

car_index = read_index("请输入要查询的车辆编号:", len(vehicles))

selected = vehiclescar_index

#多态调用:子类对象执行重写后的 describe

print("查询结果:", selected.describe())

#查询完成后询问用户是再次查询还是退出程序

again = input("是否再次查询信息?(y=继续 / 其他=退出):").strip().lower()

if again != "y":

print("感谢使用,查询系统已退出。")

break

思路 :继承结构没动,升级的是怎么用这些对象。子类 describe 改成 这是一辆 {year} 年产的 {make} {model},既用继承来的 make/model,又加自己的 year,重写不再丢信息。

真正的变化在外层交互。单辆车太寒碜,我建了个 vehicle_types 字典:键是类别,值是一串 Car 对象。这就是"列表装对象"的升级版------字典套列表,天然适合"先分类、再在类里挑"的两级结构。

两级菜单都要"输一个 1~N 的编号",我不写两遍,抽成 read_index(prompt, count),范围上限当参数传进去,复用给类别层和车辆层。这里用了标志位循环 while not valid,跳出后统一 return,绕开 PyCharm 对 while True 可能返回 None 的误判。

最后走一遍:列类别 → 选类别 → 列该车队 → 选车 → selected.describe()。这句正是多态的实战:不管 selected 是哪辆车,统一调 describe(),各自执行自己那版重写。父类子类一套接口、多种表现,这题算是把继承主题圆上了。

相关推荐
Dovis(誓平步青云)6 小时前
启元 T1 Pro 视觉伺服实践:基于 HSV 阈值与针孔测距的启元机器人寻物实现
开发语言·人工智能·机器学习·二次开发
weixin199701080166 小时前
官方授权通道和灰色爬虫,做数据服务该选哪条路(附 python 源码)
c++·爬虫·python
Ryan-Zhong6 小时前
数字人口播视频 API 实战:Python 跑通模板合成、异步轮询与批量出片
开发语言·python·音视频
努力努力再努力wz6 小时前
【Lua 入门系列】模块与包(一):从多文件组织到require 运行时加载机制、模块缓存、预加载搜索与 Lua 文件搜索机制
开发语言·junit·lua
quantdash_cc6 小时前
个人开发者用 QuantDash 读取港股行情:00700.HK 的 Python 函数封装与校验实践
python·数据分析·pandas·量化交易·股票数据·quantdash
fengci.6 小时前
CTF2困难部分
开发语言·网络·python·安全·php
佳得动6 小时前
编译和链接的认识(C语言)
c语言·开发语言
小小张说故事6 小时前
Python 的 0.1 + 0.2 为什么不等于 0.3?拆开 IEEE 754 与那串死循环小数
后端·python
LK_077 小时前
【Agent】工具调用的安全边界:从模型输出到程序执行
人工智能·笔记·python·agent