30天学会Python编程:8. Python面向对象编程
当前位置:点晴教程→知识管理交流
→『 技术文档交流 』
|
__init__ | ||
类名.属性 实例.属性 | ||
注意事项:
继承允许创建新类(子类)基于现有类(父类),实现代码复用和功能扩展。
基本语法:
class ChildClass(ParentClass):
# 子类特有属性和方法
pass
继承示例:
class Animal:
"""动物基类"""
def__init__(self, name):
self.name = name
defspeak(self):
"""抽象方法,子类必须实现"""
raise NotImplementedError("子类必须实现speak方法")
classDog(Animal):
"""狗类,继承自动物"""
defspeak(self):
returnf"{self.name}说:汪汪!"
deffetch(self, item):
"""狗特有方法"""
returnf"{self.name}捡回了{item}"
classCat(Animal):
"""猫类,继承自动物"""
defspeak(self):
returnf"{self.name}说:喵喵~"
defclimb(self, height):
"""猫特有方法"""
returnf"{self.name}爬上了{height}米高的树"
# 多态演示
animals = [Dog("阿黄"), Cat("小花")]
for animal in animals:
print(animal.speak()) # 调用不同实现
子类可以重写父类方法,使用super()
调用父类实现:
class SmartAccount(BankAccount):
"""智能账户,继承自BankAccount"""
def __init__(self, owner, balance=0, phone=""):
super().__init__(owner, balance) # 调用父类构造方法
self.phone = phone # 新增属性
def withdraw(self, amount):
"""重写取款方法,增加短信通知"""
result = super().withdraw(amount) # 调用父类方法
print(f"短信通知{self.phone}: 取出{amount}元,余额{result}元")
return result
多态的优势:
Python使用双下划线方法(魔术方法)实现特殊行为:
__init__ | ||
__str__ | print(obj) | |
__repr__ | repr(obj) | |
__len__ | len(obj) | |
__getitem__ | obj[key] | |
__setitem__ | obj[key] = value | |
__add__ | obj + other |
class Vector:
"""二维向量类"""
def__init__(self, x, y):
self.x = x
self.y = y
def__add__(self, other):
"""向量加法重载"""
return Vector(self.x + other.x, self.y + other.y)
def__mul__(self, scalar):
"""向量数乘重载"""
ifisinstance(scalar, (int, float)):
return Vector(self.x * scalar, self.y * scalar)
raise TypeError("标量必须是数值类型")
def__str__(self):
"""用户友好字符串表示"""
returnf"Vector({self.x}, {self.y})"
def__repr__(self):
"""解释器友好字符串表示"""
returnf"Vector({self.x}, {self.y})"
# 使用示例
v1 = Vector(2, 3)
v2 = Vector(1, 4)
v3 = v1 + v2 # 调用__add__
print(v3) # 调用__str__
v4 = v1 * 3 # 调用__mul__
print(v4)
@property允许将方法作为属性访问,实现封装和数据验证:
class Temperature:
"""温度类,使用属性装饰器"""
def__init__(self, celsius):
self.celsius = celsius # 使用setter
@property
defcelsius(self):
"""获取摄氏温度"""
returnself._celsius
@celsius.setter
defcelsius(self, value):
"""设置摄氏温度,带验证"""
if value < -273.15:
raise ValueError("温度不能低于绝对零度(-273.15°C)")
self._celsius = value
@property
deffahrenheit(self):
"""只读的华氏温度属性"""
returnself._celsius * 9/5 + 32
# 使用
temp = Temperature(25)
print(f"华氏温度: {temp.fahrenheit}") # 77.0
temp.celsius = 30# 调用setter
描述符提供更强大的属性控制机制:
class PositiveNumber:
"""正数描述符"""
def__set_name__(self, owner, name):
self.storage_name = name # 存储属性名
def__get__(self, instance, owner):
return instance.__dict__.get(self.storage_name, 0)
def__set__(self, instance, value):
if value <= 0:
raise ValueError("值必须为正数")
instance.__dict__[self.storage_name] = value
classCircle:
"""圆类,使用描述符控制半径"""
radius = PositiveNumber() # 描述符实例
def__init__(self, radius):
self.radius = radius # 调用描述符__set__
@property
defarea(self):
return3.14 * self.radius ** 2
# 使用
c = Circle(5)
print(c.area) # 78.5
c.radius = 10
# c.radius = -1 # 引发ValueError
class Date:
"""日期类"""
def__init__(self, year, month, day):
self.year = year
self.month = month
self.day = day
@classmethod
deffrom_string(cls, date_str):
"""类方法:替代构造函数"""
year, month, day = map(int, date_str.split('-'))
return cls(year, month, day) # 创建并返回实例
@staticmethod
defis_valid(date_str):
"""静态方法:验证日期格式"""
try:
year, month, day = map(int, date_str.split('-'))
return1 <= month <= 12and1 <= day <= 31
except ValueError:
returnFalse
def__str__(self):
returnf"{self.year}-{self.month:02d}-{self.day:02d}"
# 使用
date = Date.from_string("2023-07-20")
print(Date.is_valid("2023-02-30")) # False
抽象基类定义接口规范,强制子类实现特定方法:
from abc import ABC, abstractmethod
classShape(ABC):
"""形状抽象基类"""
@abstractmethod
defarea(self):
"""计算面积"""
pass
@abstractmethod
defperimeter(self):
"""计算周长"""
pass
classCircle(Shape):
"""圆形实现"""
def__init__(self, radius):
self.radius = radius
defarea(self):
return3.14 * self.radius ** 2
defperimeter(self):
return2 * 3.14 * self.radius
classRectangle(Shape):
"""矩形实现"""
def__init__(self, width, height):
self.width = width
self.height = height
defarea(self):
returnself.width * self.height
defperimeter(self):
return2 * (self.width + self.height)
# 使用
shapes = [Circle(5), Rectangle(4, 6)]
for shape in shapes:
print(f"面积: {shape.area()}, 周长: {shape.perimeter()}")
class Product:
"""商品基类"""
def__init__(self, name, price, stock):
self.name = name
self.price = price
self.stock = stock
defapply_discount(self, percent):
"""应用折扣"""
ifnot0 <= percent <= 100:
raise ValueError("折扣率必须在0-100之间")
self.price *= (1 - percent/100)
def__str__(self):
returnf"{self.name} - ¥{self.price:.2f} (库存: {self.stock})"
classDigitalProduct(Product):
"""数码商品"""
def__init__(self, name, price, stock, license_key):
super().__init__(name, price, stock)
self.license_key = license_key
defactivate(self, user):
"""激活许可证"""
print(f"{user} 已激活产品 {self.name}, 许可证: {self.license_key}")
classShoppingCart:
"""购物车"""
def__init__(self):
self.items = [] # 存储(商品, 数量)元组
defadd_item(self, product, quantity=1):
"""添加商品到购物车"""
if quantity <= 0:
raise ValueError("数量必须大于0")
if quantity > product.stock:
raise ValueError(f"{product.name}库存不足")
self.items.append((product, quantity))
defremove_item(self, product):
"""从购物车移除商品"""
self.items = [(p, q) for p, q inself.items if p != product]
deftotal(self):
"""计算总价"""
returnsum(p.price * q for p, q inself.items)
defcheckout(self):
"""结算"""
total = self.total()
print(f"结算完成,总计: ¥{total:.2f}")
for product, quantity inself.items:
product.stock -= quantity
self.items = []
# 使用
iphone = DigitalProduct("iPhone 14", 6999, 10, "XYZ-123-ABC")
python_book = Product("Python编程", 99, 50)
cart = ShoppingCart()
cart.add_item(iphone)
cart.add_item(python_book, 3)
cart.checkout()
print(f"{iphone.name}剩余库存: {iphone.stock}") # 9
class Character:
"""游戏角色基类"""
def__init__(self, name, health, attack_power):
self.name = name
self.health = health
self.max_health = health
self.attack_power = attack_power
self.skills = []
deftake_damage(self, damage):
"""受到伤害"""
self.health = max(0, self.health - damage)
print(f"{self.name}受到{damage}点伤害,剩余生命: {self.health}")
returnself.is_dead()
defis_dead(self):
"""检查是否死亡"""
returnself.health <= 0
defuse_skill(self, skill_index, target):
"""使用技能"""
if skill_index >= len(self.skills):
print("无效技能索引")
returnFalse
skill = self.skills[skill_index]
damage = self.attack_power + skill.damage
print(f"{self.name}对{target.name}使用{skill.name}!")
return target.take_damage(damage)
defheal(self, amount):
"""治疗"""
self.health = min(self.max_health, self.health + amount)
print(f"{self.name}恢复了{amount}点生命,当前生命: {self.health}")
classSkill:
"""技能类"""
def__init__(self, name, damage, cost):
self.name = name
self.damage = damage
self.cost = cost
def__str__(self):
returnf"{self.name}(伤害:{self.damage}, 消耗:{self.cost})"
classWarrior(Character):
"""战士职业"""
def__init__(self, name):
super().__init__(name, health=150, attack_power=20)
self.skills = [
Skill("重击", 15, 10),
Skill("旋风斩", 30, 25)
]
defshield_block(self):
"""战士特有技能:格挡"""
print(f"{self.name}举盾格挡下一次攻击")
classMage(Character):
"""法师职业"""
def__init__(self, name):
super().__init__(name, health=100, attack_power=15)
self.mana = 100
self.skills = [
Skill("火球术", 40, 20),
Skill("冰冻术", 25, 15)
]
defuse_skill(self, skill_index, target):
"""重写技能使用,检查法力值"""
skill = self.skills[skill_index]
ifself.mana < skill.cost:
print(f"法力不足,无法使用{skill.name}")
returnFalse
self.mana -= skill.cost
returnsuper().use_skill(skill_index, target)
# 战斗演示
hero = Warrior("英雄")
enemy = Mage("黑暗法师")
print(f"战斗开始: {hero.name} vs {enemy.name}")
hero.use_skill(1, enemy) # 使用旋风斩
enemy.use_skill(0, hero) # 使用火球术
hero.heal(30)
"面向对象编程不是万能的,但它是组织复杂系统的强大工具。掌握OOP原则,让代码更具表现力和扩展性。"
阅读原文:原文链接