第七章:面向对象编程
类与对象
如果"类"是饼干模具,那么"对象"就是用模具压出来的饼干。模具定义了形状,但每块饼干都是独立的个体。
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