完成本章学习后,你将能够:
面向对象编程(OOP)是一种编程范式,基于“对象”的概念。对象包含数据(属性)和代码(方法)。
核心概念:
class Dog: """狗的类""" # 类属性(所有实例共享) species = "Canis familiaris" # 构造方法(初始化方法) def __init__(self, name, age): # 实例属性(每个实例独立) self.name = name self.age = age # 实例方法 def bark(self): return f"{self.name} says woof!" def get_info(self): return f"{self.name} is {self.age} years old" # 创建实例(对象) buddy = Dog("Buddy", 3) miles = Dog("Miles", 5) # 访问属性和方法 print(buddy.name) # Buddy print(buddy.age) # 3 print(buddy.species) # Canis familiaris print(buddy.bark()) # Buddy says woof! print(buddy.get_info()) # Buddy is 3 years old
class Person: def __init__(self, name, age=0): """ 构造方法,创建对象时自动调用 self指向新创建的对象实例 """ self.name = name self.age = age self._id = id(self) # 内部使用的属性 # 创建对象 p1 = Person("Alice", 25) # __init__自动调用 p2 = Person("Bob") # age使用默认值0
class Cat: # 类属性:所有实例共享 species = "Felis catus" count = 0 def __init__(self, name): # 实例属性:每个实例独立 self.name = name Cat.count += 1 # 修改类属性 # 测试 cat1 = Cat("Whiskers") cat2 = Cat("Felix") print(Cat.count) # 2 print(cat1.count) # 2(通过实例访问类属性) print(cat2.count) # 2 # 危险:通过实例赋值会创建实例属性 cat1.species = "Unknown" # 创建实例属性,不影响类属性 print(Cat.species) # Felis catus(不变) print(cat1.species) # Unknown(实例属性) print(cat2.species) # Felis catus(仍访问类属性)
class MyClass: class_var = "class variable" def __init__(self, value): self.instance_var = value # 实例方法:第一个参数是self def instance_method(self): return f"instance: {self.instance_var}" # 类方法:第一个参数是cls,可以访问类属性 @classmethod def class_method(cls): return f"class: {cls.class_var}" # 静态方法:没有特殊参数,不需要访问类或实例 @staticmethod def static_method(): return "static method" # 替代构造函数(工厂方法) @classmethod def from_string(cls, string): """从字符串创建对象""" value = int(string) return cls(value) # 使用 obj = MyClass(42) print(obj.instance_method()) # 实例方法 print(MyClass.class_method()) # 类方法 print(MyClass.static_method()) # 静态方法 # 工厂方法 obj2 = MyClass.from_string("100")
class BankAccount: def __init__(self, owner, balance=0): self.owner = owner self._balance = balance # 单下划线:约定为内部使用 self.__transaction_log = [] # 双下划线:名称改写(私有) # getter @property def balance(self): """获取余额(只读)""" return self._balance # setter @balance.setter def balance(self, value): if value < 0: raise ValueError("Balance cannot be negative") self._balance = value def deposit(self, amount): if amount <= 0: raise ValueError("Amount must be positive") self._balance += amount self.__log_transaction(f"Deposit: {amount}") def __log_transaction(self, message): """私有方法""" self.__transaction_log.append(message) # 使用 account = BankAccount("Alice", 100) print(account.balance) # 访问属性(实际调用getter) # account.balance = -50 # ValueError account.deposit(50) # 通过方法修改 print(account.balance) # 150 # 名称改写 # print(account.__transaction_log) # AttributeError print(account._BankAccount__transaction_log) # 可以访问但不推荐
class Vector: def __init__(self, x, y): self.x = x self.y = y # 字符串表示 def __str__(self): # 用户友好 return f"Vector({self.x}, {self.y})" def __repr__(self): # 开发者友好,eval(repr(obj))应该能重建对象 return f"Vector({self.x!r}, {self.y!r})" # 算术运算 def __add__(self, other): return Vector(self.x + other.x, self.y + other.y) def __sub__(self, other): return Vector(self.x - other.x, self.y - other.y) def __mul__(self, scalar): return Vector(self.x * scalar, self.y * scalar) # 比较 def __eq__(self, other): return self.x == other.x and self.y == other.y # 长度 def __len__(self): return int((self.x ** 2 + self.y ** 2) ** 0.5) # 可调用 def __call__(self): return f"Vector at ({self.x}, {self.y})" # 使用 v1 = Vector(2, 3) v2 = Vector(1, 1) print(v1 + v2) # Vector(3, 4) print(v1 * 3) # Vector(6, 9) print(v1 == v2) # False print(len(v1)) # 3 print(v1()) # Vector at (2, 3)
1. 设计类:设计一个Rectangle类,包含面积、周长计算方法 2. 银行账户:实现支持存取款的BankAccount类,包含利息计算 3. 图书管理:实现Book和Library类,支持借还书功能 4. 向量类扩展:为Vector类添加更多数学运算 5. 温度类:实现支持摄氏华氏转换的Temperature类