什么是面向对象编程(OOP)?它与面向过程有什么不同?
学习编程时,你一定会遇到这个词。
“这段代码应该用面向对象的方式编写。”
第一次听到时,确实会让人感到困惑。面向过程是什么?面向对象到底有什么不同?一时很难理解。
先说结论:面向过程关注“要按什么顺序做什么”,而面向对象更强调“谁来负责这件事”。区别在于,是否把数据和处理这些数据的功能放在一起。
本文会用点咖啡的例子,轻松讲解两者的区别,并展示它们在实际代码中的不同。
面向过程编程就像一份烹饪食谱
面向过程顾名思义,关注的是“过程”,也就是顺序。
数据和处理数据的函数彼此分开,程序按照顺序从上到下执行。
想想烹饪食谱就很贴切:清洗、切碎、翻炒,再装盘。把这个顺序原样写进代码,就是面向过程编程。
来看一个简单的账户示例。
var balance = 10000 // 数据
func deposit(amount: Int) { // 功能分开
balance += amount
}
deposit(amount: 5000)
print(balance)
// 输出: 15000
balance 数据暴露在外部,deposit 函数会直接修改它。
对于小型程序,这反而更简单、更快。问题会在程序变大时出现。
当账户增加到100个,修改余额的函数又散落各处时,要追踪数值在哪里发生变化会非常困难。
什么是面向对象编程(OOP)?
面向对象会把数据和功能组合成一个整体,这个整体称为“对象”。
以账户为例,就是把“余额”数据和“存款”功能组合成一个单元。
把刚才的账户改成对象来看看。
class Account {
private var balance = 10000 // 将数据隐藏在内部
func deposit(_ amount: Int) { // 功能也放在一起
balance += amount
}
func show() { print(balance) }
}
let myAccount = Account()
myAccount.deposit(5000)
myAccount.show()
// 输出: 15000
balance 现在被隐藏为 private。外部不能再随意修改余额,只能通过 deposit 等规定的入口访问。
这就是面向对象的核心:保护数据,并明确“谁负责这件事”。
用点咖啡来比喻:面向过程是自己磨咖啡豆、烧水,什么都自己做;面向对象则是交给别人,说一句“咖啡师,请来一杯美式”。怎么制作,由咖啡师对象自行负责。
OOP 的4个核心特征
面向对象有四根支柱。术语看起来很难,但概念其实很简单。
- 封装:隐藏数据,只允许通过规定的入口访问(就像上面的 private)
- 继承:继承现有类的功能并重复利用
- 多态:相同的命令对不同对象产生不同的行为
- 抽象:隐藏复杂的内部细节,只暴露必要内容
多态尤其强大。让它“叫一声”时,狗会汪汪叫,猫会喵喵叫。命令只有一个,但每个对象会自动做出不同的响应。
什么时候使用面向对象,什么时候面向过程更合适
面向对象并不总是正确答案,要根据情况选择。
| 情况 | 适合的方式 |
|---|---|
| 短脚本、一次性计算 | 面向过程 |
| 数据流简单且按顺序执行 | 面向过程 |
| 规模较大且持续增长的项目 | 面向对象 |
| 多人协作开发的代码 | 面向对象 |
| 相似概念反复出现 | 面向对象 |
规模小且简单时,面向过程反而更简洁;如果代码规模大、复杂且需要长期维护,面向对象就能发挥优势。
面向过程设计顺序,面向对象设计责任。
面试时会这样问
问:面向过程和面向对象最大的区别是什么? 答:数据与功能的关系。面向过程将数据和函数分开,围绕顺序执行;面向对象则把两者组合成对象,按责任单元管理。因此,规模越大,越有利于维护和协作。
问:为什么封装很重要? 答:它能阻止外部直接修改数据,减少意外变更。由于只能通过规定的方法访问,因此更容易追踪错误;即使修改内部实现,也较少影响外部代码。
即使术语听起来很宏大,核心其实只有一个问题:“该如何处理数据?”
从小段代码开始练习将其组合成对象,很快就能掌握要领。希望你能用今天学到的内容,重构自己代码中的一小部分。

