Python练习(6)Python面向对象编程三大特性:封装、继承与多态的15道实战练习题(含答案与深度解析)
目录

引言
在Python编程中,面向对象编程(OOP)的三大特性——封装、继承和多态,是构建复杂软件系统的核心基石。封装实现了数据与操作的有机统一,继承促进了代码的复用与扩展,多态则赋予了程序灵活的接口适配能力。本文通过15道精心设计的实战练习题,系统梳理三大特性的实现机制与典型应用场景,帮助读者构建完整的OOP知识体系。
封装篇(5题)
练习1:银行账户安全封装
classBankAccount:def__init__(self, account_number, initial_balance): self.__account_number = account_number # 私有属性 self._balance = initial_balance # 受保护属性defdeposit(self, amount):if amount >0: self._balance += amount print(f"存款成功,当前余额:{self._balance}")else:print("存款金额必须大于0")defwithdraw(self, amount):if0< amount <= self._balance: self._balance -= amount print(f"取款成功,当前余额:{self._balance}")else:print("余额不足或取款金额无效")defget_balance(self):# 公共接口访问受保护属性return self._balance # 测试代码 account = BankAccount("123456",1000) account.deposit(500) account.withdraw(200)print(account.get_balance())# 通过公共方法获取余额答案与解析:
# 执行结果:# 存款成功,当前余额:1500# 取款成功,当前余额:1300# 1300通过双下划线实现属性私有化,使用单下划线标记受保护属性,通过公共方法提供安全访问接口。
练习2:属性装饰器控制
classPerson:def__init__(self, name, weight): self.name = name self.weight = weight # 直接赋值会绕过属性验证@propertydefweight(self):return self.__weight @weight.setterdefweight(self, value):if value >0: self.__weight = value else:print("体重必须为正数")# 测试代码 p = Person("Alice",-70)# 直接初始化会绕过验证print(p.weight)# 通过属性访问触发验证 p.weight =65# 正确设置print(p.weight)答案与解析:
# 执行结果:-70# 初始化时未触发setter验证 体重必须为正数 65@property装饰器将方法转换为属性,实现属性的安全访问与修改控制。
练习3:私有方法调用
classSecretData:def__init__(self, data): self.__data = data def__encrypt(self):# 私有方法returnf"ENC-{self.__data}"defget_encrypted(self):return self.__encrypt()# 测试代码 sd = SecretData("12345")print(sd.get_encrypted())# 正确访问方式print(sd.__encrypt())# 尝试直接访问私有方法答案与解析:
# 执行结果: ENC-12345 AttributeError:'SecretData'object has no attribute '__encrypt'私有方法通过名称重整机制(_类名__方法名)实现访问限制,只能通过公共接口调用。
练习4:受保护属性继承
classVehicle:def__init__(self, speed): self._speed = speed # 受保护属性classCar(Vehicle):defdrive(self): self._speed +=10# 子类可访问父类受保护属性# 测试代码 car = Car(60) car.drive()print(car._speed)# 直接访问受保护属性(不推荐)答案与解析:
# 执行结果:70受保护属性(单下划线开头)在子类中可直接访问,但外部代码仍可通过实例直接修改,需配合方法实现封装。
练习5:类属性封装
classConfig: __secret_key ="ABC123"# 私有类属性@classmethoddefget_secret(cls):return cls.__secret_key # 测试代码print(Config.get_secret())print(Config.__secret_key)# 尝试直接访问答案与解析:
# 执行结果: ABC123 AttributeError:typeobject'Config' has no attribute '__secret_key'私有类属性通过名称重整保护,只能通过类方法访问,实现配置参数的安全封装。
继承篇(5题)
练习6:单继承与方法重写
classAnimal:defspeak(self):print("动物发出声音")classDog(Animal):defspeak(self):# 方法重写print("汪汪叫")# 测试代码 animals =[Animal(), Dog()]for a in animals: a.speak()答案与解析:
# 执行结果: 动物发出声音 汪汪叫 子类通过重写父类方法实现多态,super().speak()可调用父类原始实现。
练习7:多继承与MRO
classA:defprocess(self):print("A处理")classB(A):defprocess(self):print("B处理前")super().process()classC(A):defprocess(self):print("C处理前")super().process()classD(B, C):pass# 测试代码 D().process()print(D.mro())# 查看方法解析顺序答案与解析:
# 执行结果: B处理前 C处理前 A处理 [<class'__main__.D'>,<class'__main__.B'>,<class'__main__.C'>,<class'__main__.A'>,<class'object'>]多继承遵循C3线性化算法,super()按MRO顺序调用父类方法。
练习8:抽象基类实现
from abc import ABC, abstractmethod classPayment(ABC):@abstractmethoddefpay(self, amount):passclassCreditCard(Payment):defpay(self, amount):print(f"信用卡支付{amount}元")# 测试代码 card = CreditCard() card.pay(100)答案与解析:
# 执行结果:信用卡支付100元抽象基类通过@abstractmethod强制子类实现特定接口,确保多态行为的规范性。
练习9:Mixin模式
classLoggerMixin:deflog(self, message):print(f"[LOG] {message}")classDatabase:defsave(self): self.log("数据保存")classEnhancedDB(LoggerMixin, Database):pass# 测试代码 db = EnhancedDB() db.save()答案与解析:
# 执行结果:[LOG] 数据保存Mixin类通过多继承为其他类添加横切关注点(如日志),提升代码复用性。
练习10:super()函数应用
classA:def__init__(self):print("A初始化")super().__init__()classB(A):def__init__(self):print("B初始化")super().__init__()classC(B):def__init__(self):print("C初始化")super().__init__()# 测试代码 C()答案与解析:
# 执行结果: C初始化 B初始化 A初始化 super()在菱形继承结构中按MRO顺序调用,确保所有父类初始化逻辑执行。
多态篇(5题)
练习11:接口多态
classShape:defarea(self):raise NotImplementedError classCircle(Shape):def__init__(self, radius): self.radius = radius defarea(self):return3.14* self.radius **2classRectangle(Shape):def__init__(self, w, h): self.w = w self.h = h defarea(self):return self.w * self.h # 测试代码 shapes =[Circle(5), Rectangle(4,6)] total =sum(s.area()for s in shapes)print(total)答案与解析:
# 执行结果:78.5 + 24 = 102.5不同形状类实现相同接口方法,通过统一接口计算总面积,体现多态特性。
练习12:鸭子类型
classDuck:defquack(self):print("嘎嘎叫")classPerson:defquack(self):print("模仿鸭子叫")defmake_quack(obj): obj.quack()# 测试代码 make_quack(Duck()) make_quack(Person())答案与解析:
# 执行结果: 嘎嘎叫 模仿鸭子叫 Python动态类型语言通过鸭子类型实现多态,只要对象具有相同方法名即可。
练习13:多态与异常处理
classFileHandler:defread(self):raise NotImplementedError classTextFile(FileHandler):defread(self):return"文本内容"classImageFile(FileHandler):defread(self):returnb"\x89PNG\r\n"defprocess_file(handler):try:return handler.read()except NotImplementedError:print("未实现读取方法")# 测试代码print(process_file(TextFile()))print(process_file(ImageFile()))答案与解析:
# 执行结果: 文本内容 b'\x89PNG\r\n'抽象基类定义统一接口,子类实现不同读取逻辑,通过多态统一处理。
练习14:多态与类型检查
defserialize(obj):ifisinstance(obj,int):returnstr(obj)elifisinstance(obj,list):return",".join(serialize(i)for i in obj)else:raise TypeError("不支持的类型")# 测试代码print(serialize(123))print(serialize([1,[2,3]]))答案与解析:
# 执行结果:'123''1,2,3'通过isinstance进行类型检查,实现不同类型数据的序列化多态处理。
练习15:多态与装饰器
deflogging(func):defwrapper(*args,**kwargs):print(f"调用 {func.__name__}")return func(*args,**kwargs)return wrapper classCalculator:@loggingdefadd(self, a, b):return a + b @loggingdefmultiply(self, a, b):return a * b # 测试代码 calc = Calculator()print(calc.add(3,5))print(calc.multiply(4,2))答案与解析:
# 执行结果: 调用 add 8 调用 multiply 8装饰器为不同方法统一添加日志功能,体现多态在方法层面的应用。
总结
本文通过15道实战练习题,系统梳理了Python面向对象编程三大特性的核心知识点:
- 封装:通过私有属性、
@property装饰器和受保护成员实现数据安全与访问控制 - 继承:单继承、多继承、MRO机制和抽象基类的应用场景与实现方式
- 多态:接口多态、鸭子类型、方法重写和装饰器模式在多态中的具体实践
掌握这些核心特性,能够显著提升代码的组织能力、复用性和扩展性。建议读者通过实际编码验证每个案例,加深对面向对象编程思想的理解。