为什么要学面向对象:从写脚本到做项目

之前学 Python 都是写脚本:一行一行顺序执行,用函数把重复代码包起来。这种方式写 100 行以内的小程序很舒服,但项目一旦变大——比如要做一个游戏,里面有蛇、有食物、有障碍物——全靠函数和全局变量会乱成一锅粥。

面向对象(OOP)提供了一种新的组织方式:把数据和操作数据的函数打包成一个"类"。蛇的位置、长度、移动方法,全部封装在 Snake 类里;食物的位置、生成方法,封装在 Food 类里。代码立刻就清晰了。

面向对象不是为了炫技,而是当项目变大时,帮你把代码整理得不会失控。
本文核心知识点
  • 类一张设计图,描述一类东西长什么样、能做什么。
  • 对象按设计图造出来的具体东西。
  • 属性对象的数据,比如蛇的长度。
  • 方法对象能做的事,比如蛇移动一步。
Python 面向对象小项目配图:蓝色渐变背景上左侧星形饼干模具向右产出多个带笑脸饼干,旁边像素方块组成小蛇、一杯咖啡、一本笔记本,齿轮和蓝图漂浮
类是模具,对象是饼干。一个模具能做出无数饼干。

类与对象:饼干模具和饼干的比喻

想象你有一个星形饼干模具。模具本身不是饼干,它只是一个形状设计图。但你用它按一下面团,就能做出一块星形饼干。你可以按十次,做出十块饼干,每块饼干是独立的。

在 Python 里:类就是模具,对象就是按出来的饼干。

class Snake:
    pass

# 用类创建两个对象
s1 = Snake()
s2 = Snake()

这里 Snake 是类,s1 和 s2 是两个独立的对象。它们都是 Snake 类型,但各自独立。

属性与方法:给类加数据和行为

空类没用。我们给 Snake 加属性(数据)和方法(行为):

class Snake:
    def __init__(self):
        self.length = 3       # 属性:长度
        self.direction = "右" # 属性:方向

    def move(self):            # 方法:移动
        print("蛇向", self.direction, "移动一步")

    def grow(self):            # 方法:长大
        self.length += 1
        print("蛇现在长度", self.length)

这里 `self` 代表"对象自己"。每个对象有自己的 length 和 direction,互不干扰。

s = Snake()
s.move()        # 输出:蛇向 右 移动一步
s.grow()        # 输出:蛇现在长度 4
s.grow()        # 输出:蛇现在长度 5

属性 `self.length` 和方法 `self.move()` 都是对象的一部分。你可以把它理解成:每一条蛇都自带一份长度记录和一套移动动作。

构造函数 __init__:新建对象时做什么

`__init__` 是 Python 类里最特殊的方法,叫构造函数。你每次用 `Snake()` 创建对象时,它会自动运行一次,用来初始化对象的属性。

我们让构造函数接受参数,这样创建对象时可以指定初始长度:

class Snake:
    def __init__(self, start_length=3, direction="右"):
        self.length = start_length
        self.direction = direction

s1 = Snake()                    # 默认长度 3
s2 = Snake(start_length=10)     # 长度 10
print(s1.length, s2.length)      # 输出:3 10

这样一个类就能灵活地造出不同初始状态的对象。这就是面向对象的好处:写一次类,能造出无数个个性化对象。

小项目一:记账本类,记录每一笔开销

我们做一个实用小工具:记账本。它能记每一笔花销、列出所有记录、算总支出。

class Ledger:
    def __init__(self, owner):
        self.owner = owner
        self.records = []   # 空列表存记录

    def add(self, amount, note):
        self.records.append({"金额": amount, "备注": note})

    def total(self):
        return sum(r["金额"] for r in self.records)

    def show(self):
        print(f"--- {self.owner} 的账本 ---")
        for r in self.records:
            print(r["金额"], r["备注"])
        print("合计:", self.total())


mine = Ledger("小明")
mine.add(25, "奶茶")
mine.add(80, "午餐")
mine.add(12, "公交")
mine.show()

这里 Ledger 类把"记录列表""加一笔""算总和""展示"全部打包在一起。你不需要关心内部 records 怎么存,只要调用 add、show 就行。这种把实现细节藏起来、只暴露必要接口的做法叫封装,是 OOP 的第一大特性。

本节用到的核心结构
  • __init__构造函数,初始化属性。
  • self对象自己的引用,访问属性和方法。
  • 列表存记录用列表 append 每条开销。
  • 封装数据和操作打包在类里。