类和对象
基本语法
定义
class
python
class Person:
"""这是一个表示人的类"""
pass
构造函数
self
参数是对当前实例的引用,必须是第一个参数,但在调用时不需要显式传递。self
相当于this
- 其它形参是类的属性
python
class Person:
def __init__(self, name, age):
"""
初始化Person对象
参数:
name (str): 人的姓名
age (int): 人的年龄
"""
self.name = name # 实例属性
self.age = age # 实例属性
# 私有属性(名称重整)
self.__id = id(self)
创建对象
python
# 创建Person类的实例
person1 = Person("Alice", 30)
person2 = Person("Bob", 25)
# 访问实例属性
print(person1.name) # 输出: Alice
print(person2.age) # 输出: 25
实例方法
python
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def introduce(self):
"""返回一个介绍字符串"""
return f"Hi, I'm {self.name} and I'm {self.age} years old."
def have_birthday(self):
"""增加年龄"""
self.age += 1
return f"Happy Birthday! Now I'm {self.age} years old."
# 调用实例方法
person = Person("Alice", 30)
print(person.introduce()) # 输出: Hi, I'm Alice and I'm 30 years old.
print(person.have_birthday()) # 输出: Happy Birthday! Now I'm 31 years old.
类属性
类似类中
static
python
class Person:
# 类属性
species = "Homo sapiens"
count = 0
def __init__(self, name, age):
self.name = name
self.age = age
# 增加计数
Person.count += 1
# 通过类名访问类属性
print(Person.species) # 输出: Homo sapiens
print(Person.count) # 输出: 0
person1 = Person("Alice", 30)
person2 = Person("Bob", 25)
print(Person.count) # 输出: 2
print(person1.species) # 实例也可以访问类属性
修改
python
# 通过类名修改类属性,影响所有实例
Person.species = "Human"
print(person1.species) # 输出: Human
print(person2.species) # 输出: Human
# 通过实例修改属性,只影响该实例
person1.species = "Superhuman"
print(person1.species) # 输出: Superhuman
print(person2.species) # 输出: Human (不变)
print(Person.species) # 输出: Human (不变)
封装
- 公有成员:常规名称 :类内外都可访问
- 受保护成员:单下划线前缀
_
,按约定仅类内部和子类使用- 私有成员:双下划线前缀
__
,仅类内部访问,名称会重整为_类名__属性名
- 方法,变量都一样
- 名称重整:即外部无法通过对象名.私有属性访问私有成员,可以通过对象名.重整后的私有名称属性绕过
- 关于getter和setter,Python不鼓励Java/C++风格的做法【全私有,提供set和get】。Python推荐的做法是:使用公有属性
python
class BankAccount:
def __init__(self, owner, balance, account_number):
self.owner = owner
self._balance = balance
self.__account_number = account_number
def deposit(self, amount):
"""公有方法"""
if amount > 0:
self._balance += amount
self._log_transaction("deposit", amount)
def _log_transaction(self, transaction_type, amount):
"""受保护方法"""
print(f"{transaction_type}: ${amount}")
def __generate_statement(self):
"""私有方法"""
return f"Statement for {self.owner}: Balance=${self._balance}"
def get_statement(self):
"""公有方法,可以访问私有方法"""
return self.__generate_statement()
继承
class Son(Father)
super()
代表父类对象- 构造函数中需要显式调用
super().父类构造
python
# 父类
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def introduce(self):
return f"Hi, I'm {self.name} and I'm {self.age} years old."
# 子类
class Student(Person):
def __init__(self, name, age, student_id):
# 调用父类的构造函数
super().__init__(name, age)
# 添加子类特有的属性
self.student_id = student_id
def study(self):
return f"{self.name} is studying hard!"
# 创建一个Student对象
student = Student("Alice", 20, "S12345")
print(student.introduce()) # 继承自Person类的方法
print(student.study()) # Student类特有的方法
多态
- Python使用"鸭子类型"(如果它走起路来像鸭子,叫起来像鸭子,那么它就是鸭子)
- 同一个接口,不同的实现。调用代码不需要知道具体是哪个类的实例,只需要知道它提供了所需的方法。
python
# 支付处理的示例
class PaymentProcessor:
"""支付处理器的基类/接口"""
def process_payment(self, amount):
raise NotImplementedError("子类必须实现process_payment方法")
def get_payment_status(self, payment_id):
raise NotImplementedError("子类必须实现get_payment_status方法")
class CreditCardProcessor(PaymentProcessor):
"""信用卡支付处理器"""
def process_payment(self, amount):
print(f"使用信用卡处理 ${amount} 的支付")
# 信用卡特定的处理逻辑
return "CC123456789" # 返回支付ID
def get_payment_status(self, payment_id):
print(f"检查信用卡支付状态,ID: {payment_id}")
return "已完成"
class PayPalProcessor(PaymentProcessor):
"""PayPal支付处理器"""
def process_payment(self, amount):
print(f"使用PayPal处理 ${amount} 的支付")
# PayPal特定的处理逻辑
return "PP987654321" # 返回支付ID
def get_payment_status(self, payment_id):
print(f"检查PayPal支付状态,ID: {payment_id}")
return "处理中"
class BankTransferProcessor(PaymentProcessor):
"""银行转账处理器"""
def process_payment(self, amount):
print(f"使用银行转账处理 ${amount} 的支付")
# 银行转账特定的处理逻辑
return "BT543216789" # 返回支付ID
def get_payment_status(self, payment_id):
print(f"检查银行转账状态,ID: {payment_id}")
return "待验证"
# 现在,让我们看看多态如何运作
def checkout(cart_total, payment_processor):
"""结账功能 - 使用任何支付处理器处理支付"""
# 不关心payment_processor是什么类型,只关心它有process_payment方法
payment_id = payment_processor.process_payment(cart_total)
print(f"支付已处理,ID: {payment_id}")
return payment_id
def check_order_status(payment_id, payment_processor):
"""检查订单状态"""
# 同样,不关心具体是什么处理器,只关心它有get_payment_status方法
status = payment_processor.get_payment_status(payment_id)
print(f"订单状态: {status}")
return status
# 用户可以选择不同的支付方式
credit_card = CreditCardProcessor()
paypal = PayPalProcessor()
bank_transfer = BankTransferProcessor()
# 测试不同的支付方式 - 多态的体现
cart_amount = 299.99
# 用户选择信用卡
cc_payment_id = checkout(cart_amount, credit_card)
check_order_status(cc_payment_id, credit_card)
print("\n")
# 用户选择PayPal
pp_payment_id = checkout(cart_amount, paypal)
check_order_status(pp_payment_id, paypal)
print("\n")
# 用户选择银行转账
bt_payment_id = checkout(cart_amount, bank_transfer)
check_order_status(bt_payment_id, bank_transfer)
方法重写
基础是继承
python
class Animal:
def make_sound(self):
return "Some generic sound"
class Dog(Animal):
# 重写父类方法
def make_sound(self):
return "Woof!"
class Cat(Animal):
# 重写父类方法
def make_sound(self):
return "Meow!"
# 多态使用
animals = [Animal(), Dog(), Cat()]
for animal in animals:
print(animal.make_sound())