Skip to content

类和对象

基本语法

定义

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())