| 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原则,让代码更具表现力和扩展性。"
阅读原文:原文链接