从本章开始,我们将进入面向对象编程的世界。类与对象是面向对象的核心,理解它们就像学会了一套全新的思维工具。由于本章知识量较大,我们先聚焦前四节:面向对象思想、定义类、创建对象以及类的成员(包括实例变量、构造方法、实例方法、类变量、类方法)。我会用一个简单的综合案例把它们串起来,让你一次性搞懂。
一、面向对象的基本思想
面向对象(Object Oriented)是一种编程思想,它按照现实世界的思维方式来构建软件系统。
- 对象:现实中的任何事物都可以看作对象,比如一只狗、一辆车、一个银行账户。每个对象都有自己的属性(如狗狗的姓名、年龄)和行为(如狗狗会跑、会叫)。
- 类:类是对具有相同属性和行为的一类事物的抽象描述。好比“狗”这个类别描述了所有狗的共性,而具体的一只狗“球球”就是“狗”类的一个对象(也称实例)。
简单记忆:类是图纸,对象是根据图纸造出来的具体房子。
二、定义类与创建对象
# 2.1 定义类
使用class 关键字定义类,类名通常采用大驼峰命名法(首字母大写)。基本语法:
python
class 类名:
类体
# 2.2 创建对象
通过类名() 即可创建一个对象(实例)。
简单示例:
python
class Car:
pass # 空类体,什么都不做
my_car = Car() # 创建 Car 类的对象
> 实际开发中,类中通常会包含成员(变量和方法),下面我们会详细展开。
三、类的成员—— 用一个综合案例讲透
为了让你清晰理解实例变量、类变量、实例方法、类方法、构造方法的区别,我设计了一个银行账户的综合案例,涵盖所有概念,非常贴近生活。
# 综合案例:银行账户类(Account)
python
class Account:
# 类变量:所有对象共享的属性(如银行统一利率)
interest_rate = 0.025 # 年利率 2.5%
# 构造方法:在创建对象时自动调用,用来初始化实例变量
def __init__(self, owner, amount):
self.owner = owner # 实例变量:每个账户特有的户主名
self.amount = amount # 实例变量:每个账户特有的金额
# 实例方法:针对具体对象的操作,需要具体对象的数据
def deposit(self, money):
"""存款"""
self.amount += money
print(f"{self.owner} 存入 {money} 元,余额 {self.amount} 元")
def withdraw(self, money):
"""取款"""
if money <= self.amount:
self.amount -= money
print(f"{self.owner} 取出 {money} 元,余额 {self.amount} 元")
else:
print("余额不足")
# 类方法:针对类本身的操作,不依赖具体对象
@classmethod
def get_interest(cls, amount):
"""根据金额计算一年利息"""
return amount * cls.interest_rate
# ---------- 创建对象并演示 -------acc1 = Account("张三", 10000)
acc2 = Account("李四", 5000)
# 访问实例变量(每个对象独有的)
print(acc1.owner, acc1.amount) # 张三 10000
print(acc2.owner, acc2.amount) # 李四 5000
# 调用实例方法
acc1.deposit(2000) # 张三存入2000,余额12000
acc2.withdraw(800) # 李四取出800,余额4200
# 访问类变量(通过类名访问,推荐)
print(Account.interest_rate) # 0.025
# 调用类方法(通过类名调用)
interest = Account.get_interest(10000)
print(f"一万元的一年利息: {interest} 元") # 一万元的一年利息: 250.0 元
四、核心概念区分与理解(重要笔记)
# 属性(数据) → 变量:存储对象的状态
- 实例变量:每个对象的特有属性。
- 定义:在构造方法或实例方法中用 self.变量名 = 值。
- 访问:对象名.变量名。
- 案例示例:acc1.owner、acc2.amount。
- 类变量:所有对象共享的属性。
- 定义:直接写在类中,不在任何方法内。
- 访问:类名.变量名(推荐)。
- 案例示例:Account.interest_rate。
# 行为(操作) → 方法:执行某种动作或计算
- 实例方法:针对具体对象的操作。
- 定义:第一个参数为 self。
- 访问:对象名.方法名()。
- 案例示例:acc1.deposit(2000)、acc2.withdraw(800)。
- 类方法:针对类本身的操作,不依赖具体对象。
- 定义:使用 @classmethod 装饰,第一个参数为 cls。
- 访问:类名.方法名()。
- 案例示例:Account.get_interest(10000)。
- 构造方法 __init__:特殊的初始化方法,在创建对象时自动调用,用于给新对象的实例变量赋初值。
- 定义:def __init__(self, 参数列表):。
- 访问:创建对象时自动调用(对象名 = 类名(参数))。
- 案例示例:acc1 = Account("张三", 10000) 触发 __init__ 执行。
五、常见误区与使用建议
- 误区1:类方法可以通过对象调用吗?
可以,但不推荐。例如acc1.get_interest(10000) 也能工作,但会让人困惑。始终用 类名.类方法() 调用,意图更清晰。
- 误区2:实例方法能不能操作类变量?
能。实例方法可以通过self.__class__.interest_rate 或 Account.interest_rate 访问类变量。但反过来,类方法不能操作实例变量,因为没有 self。
- 误区3:构造方法是实例方法吗?
形式上类似,但__init__ 是特殊的初始化方法,不是普通的行为。你通常不会手动调用它。
- 建议:
- 如果方法内部需要访问实例变量(如 self.amount),一定用实例方法。
- 如果方法内部不需要实例变量,只需要类变量或进行与类相关的计算,用类方法。
- 如果方法完全不需要访问类或实例的任何属性,可以考虑用静态方法(@staticmethod),本章未涉及,可后续学习。
记忆口诀:
- 实例变量是“我的”,类变量是“我们的”。
- 实例方法做“我的事”,类方法做“我们的事”。
- 构造方法是“出生时自动贴标签”。