Skip to content

第七章:面向对象编程

类与对象

如果"类"是饼干模具,那么"对象"就是用模具压出来的饼干。模具定义了形状,但每块饼干都是独立的个体。

bash
# 定义一个"狗"类
class Dog:
    # 类变量:所有实例共享
    species = "犬科"

    # __init__ 是构造方法,创建对象时自动调用
    def __init__(self, name, age, breed):
        # 实例变量:每个实例独有
        self.name = name
        self.age = age
        self.breed = breed

    # 实例方法
    def bark(self):
        return f"🐕 {self.name}说:汪汪!"

    def info(self):
        return f"{self.name}是{self.breed},今年{self.age}岁"

# 创建对象(实例化)
dog1 = Dog("旺财", 3, "金毛")
dog2 = Dog("来福", 5, "柯基")

print(dog1.bark())
print(dog2.info())
print(f"品种:{dog1.species}")
bash
🐕 旺财说:汪汪!
来福是柯基,今年5岁
品种:犬科

继承

bash
# 父类
class Animal:
    def __init__(self, name, sound):
        self.name = name
        self.sound = sound

    def speak(self):
        return f"{self.name}说:{self.sound}!"

# 子类继承父类
class Cat(Animal):
    def __init__(self, name, indoor=True):
        super().__init__(name, sound="喵")  # 调用父类构造方法
        self.indoor = indoor

    def purr(self):  # 子类特有的方法
        return f"{self.name}在打呼噜...呼噜呼噜 😺"

class Duck(Animal):
    def __init__(self, name):
        super().__init__(name, sound="嘎嘎")

    def swim(self):
        return f"{self.name}在水里游泳 🏊"

cat = Cat("咪咪")
duck = Duck("唐老鸭")

print(cat.speak())  # 继承的方法
print(cat.purr())   # 子类的方法
print(duck.speak())
print(duck.swim())
bash
咪咪说:喵!
咪咪在打呼噜...呼噜呼噜 😺
唐老鸭说:嘎嘎!
唐老鸭在水里游泳 🏊

多态

bash
class Shape:
    def area(self):
        raise NotImplementedError("子类必须实现 area 方法")

class Circle(Shape):
    def __init__(self, radius):
        self.radius = radius

    def area(self):
        import math
        return math.pi * self.radius ** 2

class Rectangle(Shape):
    def __init__(self, width, height):
        self.width = width
        self.height = height

    def area(self):
        return self.width * self.height

# 多态:同样的接口,不同的行为
shapes = [Circle(5), Rectangle(4, 6), Circle(3)]
for shape in shapes:
    print(f"{shape.__class__.__name__} 面积 = {shape.area():.2f}")
bash
Circle 面积 = 78.54
Rectangle 面积 = 24.00
Circle 面积 = 28.27

封装与魔术方法

bash
# 封装:用 _ 和 __ 控制访问权限
class BankAccount:
    def __init__(self, owner, balance=0):
        self.owner = owner          # 公开属性
        self._bank = "Python银行"    # 约定私有(只是建议,仍可访问)
        self.__balance = balance    # 名称修饰(更严格)

    def deposit(self, amount):
        if amount > 0:
            self.__balance += amount
            return f"存入 {amount} 元,余额 {self.__balance} 元"
        return "存款金额必须为正数"

    def withdraw(self, amount):
        if 0 < amount <= self.__balance:
            self.__balance -= amount
            return f"取出 {amount} 元,余额 {self.__balance} 元"
        return "余额不足"

    # 魔术方法:让对象有特殊行为
    def __str__(self):
        # print() 时调用
        return f"[{self.owner}的账户] 余额:{self.__balance}元"

    def __repr__(self):
        # 调试时调用
        return f"BankAccount('{self.owner}', {self.__balance})"

    def __len__(self):
        # len() 时调用,这里返回余额的"位数"
        return len(str(self.__balance))

account = BankAccount("小明", 1000)
print(account)
print(account.deposit(500))
print(account.withdraw(200))
print(repr(account))
print(f"余额位数:{len(account)}")
bash
[小明的账户] 余额:1000元
存入 500 元,余额 1500
取出 200 元,余额 1300
BankAccount('小明', 1300)
余额位数:4