====== 第十三章:面向对象编程基础 ======
===== 本章目标 =====
完成本章学习后,你将能够:
* 理解面向对象编程的核心概念
* 定义类和创建对象
* 使用属性和方法
* 理解self和__init__
* 掌握类变量和实例变量
===== 面向对象基础概念 =====
==== 什么是面向对象编程 ====
面向对象编程(OOP)是一种编程范式,基于"对象"的概念。对象包含**数据**(属性)和**代码**(方法)。
核心概念:
* **类(Class)** —— 对象的蓝图/模板
* **对象(Object)** —— 类的实例
* **属性(Attribute)** —— 对象的数据
* **方法(Method)** —— 对象的行为
* **封装(Encapsulation)** —— 隐藏内部实现
* **继承(Inheritance)** —— 基于现有类创建新类
* **多态(Polymorphism)** —— 同一接口,不同实现
===== 定义类 =====
==== 基本语法 ====
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
==== __init__方法 ====
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
===== 类属性 vs 实例属性 =====
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类
===== 本章小结 =====
本章我们学习了:
* 面向对象的基本概念
* 类的定义和对象的创建
* 类属性和实例属性的区别
* 三种方法类型
* 属性装饰器
* 特殊方法
下一章:[[python_course:chapter14|第十四章:继承与多态]]