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(),各自执行自己那版重写。父类子类一套接口、多种表现,这题算是把继承主题圆上了。

相关推荐
老唐7771 小时前
Agent 开发入门教程:从零搭建一个 Python AI Agent
人工智能·python·深度学习·langchain·大模型·agent·智能体
宿州派大星4 小时前
Python实战:PyQt5 + OpenCV + Dlib 打造AI桌面应用
人工智能·python·qt
承渊政道5 小时前
【从零开始大模型开发与微调:基于PyTorch与ChatGLM】(开源大模型ChatGLM高级定制化应用实战)
人工智能·pytorch·python·llm·模型微调·glm
Joy T6 小时前
Agent 确定性上下文设计:从 Prompt 参数注入到能力分层
java·开发语言·微服务·架构·prompt·agent context
专注仿真10 小时前
引擎扩展性与集成设计深度剖析:从 14 个扩展点到 DIS→HLA 演进之路
开发语言·算法·仿真引擎·推演引擎
Best-Wishes10 小时前
科来网络分析系统(技术交流版)使用说明书
开发语言·junit·php
代码不停11 小时前
自动化测试(java)
java·开发语言·selenium·自动化
Smoothcloud润云11 小时前
PyTorch大模型权重加载与启动耗时优化实战:定位磁盘、内存与显存瓶颈
人工智能·pytorch·python·深度学习·gpu算力
databook11 小时前
从循环到向量化:NumPy提速的7个关键思维
python·数据分析·numpy