几乎所有程序员的入门路上都绕不开“面向对象”这四个字,但能把封装、抽象、继承、多态一次讲清、且多年长青霸榜的视频极少。Programming with Mosh 的《Object-Oriented Programming, Simplified》就是其中之一:不堆语法、不灌名词,一张 UML 类图贯穿全片,给每个支柱都配了一句“收益注脚”,被无数博客和课程反复引用。本文按视频叙事逐层拆解,补上它来不及展开的六十年理论前史与社区争议,并审查四大支柱里哪一条最经不起推敲。看完这篇,你不仅知道 OOP 是什么,还知道它什么时候不该用。
| 项目 | 内容 |
|---|---|
| 视频标题 | Object-Oriented Programming, Simplified(面向对象编程,简化讲法) |
| 频道 | Programming with Mosh(主讲人 Mosh Hamedani,编程教育者,以 C#、Python、Java 系列课程知名) |
| 分类 | 编程基础 / 软件设计 |
| 发布时间 | 长青经典,2019年前后发布(据频道页面;本环境未能实时核验精确日期) |
| 播放量 | 4,857,455 次(2026-09-15 00:02 UTC 系统预抓取快照) |
| 时长 | 十几分钟量级 |
数据核验说明:本文写作于离线沙箱环境,无法实时联网。视频标题、频道名、播放量与链接来自系统当日通过 yt-dlp 对 YouTube 检索结果的真实预抓取,属可信快照;发布精确日期与频道订阅数未能核验,不作编造。文中涉及的理论、人物、著作为公开文献可查的独立事实。
这条视频最聪明的地方,是从动机讲起,而不是从语法讲起。Mosh 开篇先描述过程式编程的困境:数据和操作数据的函数散落在程序各处,任何一处改动都可能牵动全身,项目越大越是如此。OOP 给出的答案朴素得惊人——把相关的数据和操作它们的函数,打包放进同一个单元。这个单元就是类(class),类是蓝图;按蓝图造出来的具体个体,就是对象(object)。
视频用桌面应用的场景贯穿这个概念:一个窗口(Window)里摆着文本框(TextBox)、下拉框(ComboBox)这类控件,每个控件都是一个对象,各自管理自己的外观、内容和被点击时的行为。窗口不需要知道文本框内部怎么画的字,只需要知道“你能显示、你能接收输入”。这个“不需要知道”,就是后面两大支柱的伏笔。
值得指出的是,Mosh 从第一分钟就在做一件事:把“面向对象”从玄学拉回工程。类不是哲学概念,它是一个打包方案——打包是为了让复杂度有地方可藏。理解了这一句,四大支柱才不是四条需要背诵的名词,而是四种具体的“藏法”。
视频的前两根支柱,封装(Encapsulation)与抽象(Abstraction),是初学者最容易混为一谈的,Mosh 的处理方式是给每根支柱配一句“收益注脚”,这行注脚正是全片被引用最多的部分:
封装的具体做法,是把字段设为私有(private),外界只能通过公开方法读写。Mosh 强调这不是“安全措施”,而是控制权:数据只能以类允许的方式被修改。比如一个文本框的内部状态,外界不该直接扒开改,只能调用它提供的接口——类由此获得了一层“膜”。
抽象则是在封装之上再砍一层:调用方只需要知道对象“做什么”,不需要知道“怎么做”。视频里的比喻很日常——你按遥控器的音量键,不需要懂电视内部的信号处理。Mosh 给抽象的注脚是“隔离变化的影响”:只要接口不变,实现可以随意重构,调用方代码一行不用动。
两者的分界线,可以这样记:封装管“藏”(对内保护状态),抽象管“简”(对外收窄接口)。一个是墙,一个是门。这对概念后来在工程界有个更古老的名字——信息隐藏(information hiding),比 OOP 这个词本身还要早问世几十年,本文第五节会回到这条线索。
第三根支柱继承(Inheritance),是四大支柱里历史包袱最重的一根。Mosh 的定义是标准的“is-a”关系:下拉框是一种文本框,所以让 ComboBox 继承 TextBox,子类自动获得父类的全部能力,只需补充差异部分。视频给出的收益注脚是:消除冗余代码。
这是 1990 年代到 2000 年代教科书的标准叙事,也是 OOP 曾经被神化的核心原因——复用!只要把继承树设计好,代码就能像生物分类一样自动生长。视频在这部分保持了入门课的克制,没有展开继承的阴暗面,但作为读者你必须知道:“消除冗余”是四条注脚里唯一被现代工程界大规模修正的一条。子类继承的不只是父类的行为,还有父类的实现细节——父子从此被焊死在同一份实现上,改基类一行,满门抄斩。这个问题严重到有了自己的学名“脆弱基类问题(fragile base class)”,1994 年的《设计模式》原著里就已经警告过它。本文第六节会正面处理这个争议。
第四根支柱多态(Polymorphism),是全片的高潮,也是 Mosh 案例设计的点睛之处。窗口里的控件们——文本框、下拉框——都对“被绘制”“被点击”这两条消息做出了各自的回应:同一个方法名,落在不同对象身上,行为各自实现。调用方(窗口)完全不需要写“如果控件类型是 A 就做 X,如果是 B 就做 Y”的判断分支。
这就是那条著名注脚的含义:多态让你重构掉丑陋的 switch/case 语句。类型判断分支是过程式代码处理“多种同类事物”的方式,多态把“按类型分派”这件事从调用方挪进了对象体系内部——新增一种控件,调用方代码零改动。
值得玩味的是视频的叙事顺序:封装 → 抽象 → 继承 → 多态,抽象程度层层递进,前三根支柱都在为最后一根铺路——没有封装就没有清晰的接口,没有抽象就没有统一的消息,没有继承就没有“同类不同形”的对象家族。全片几乎没有成段的代码,靠一张 UML 类图推演到底,示例带着鲜明的 C# 血统。这种“一张图讲完一个学科”的做法,正是它能在海量 OOP 入门片里脱颖而出的原因。
视频没时间讲的东西,恰恰是理解四大支柱的关键背景。把时间线摆出来,你会发现“四支柱”只是 OOP 六十年历史里的一个切片。
1967 年,OOP 的出生证明。挪威计算中心的 Ole-Johan Dahl 与 Kristen Nygaard 在 Simula 67 语言中第一次引入了类、子类、对象这些概念——最初是为了写离散事件仿真:把港口里的每艘船建模成一个“对象”,天然直观。两人因此在 2001 年获得图灵奖。
1960 年代末,"object-oriented"一词被发明。犹他大学研究生 Alan Kay 受 Ivan Sutherland 1963 年的 Sketchpad(已有主对象-实例思想)启发,提出用类似生物细胞的方式组织软件:对象像细胞,靠消息通信,细胞膜之内对外不可见。Kay 后来在施乐帕克(Xerox PARC)主导了 Smalltalk 语言,把这套思想做成完整体系,并在 1997 年 OOPSLA 大会做了著名演讲《The Computer Revolution Hasn't Happened Yet》。广为流传的一句引述是:“我发明了‘面向对象’这个词,但 C++ 不是我脑子里想的样子。”——在 Kay 的原意里,核心是消息传递,而不是类和继承。
1972 年,比 OOP 更老的“信息隐藏”。David Parnas 在 CACM 发表经典论文《On the Criteria to Be Used in Decomposing Systems into Modules》,提出模块划分的标准是“把难以预料的设计决策藏进模块内部”。你今天写的每一个 private 字段,学理源头都是这篇论文——这也解释了为什么封装是最没争议的支柱:它比 OOP 正典更古老、更根本。
1994 年,正典的诞生与第一声警告同时出现。GoF 四人帮(Gamma、Helm、Johnson、Vlissides)出版《Design Patterns》,把 23 个模式变成 OOP 时代的圣经;但同一本书第一章就写下那句名言:"Favor object composition over class inheritance"(优先使用对象组合而非类继承)。Liskov 女士 1987 年的演讲《Data Abstraction and Hierarchy》则给继承加上了著名的里氏替换原则约束——子类必须能无感替换父类。
2000 年之后的反方阵营。Robert C. Martin 提出 SOLID 五原则,继续给 OOP 立规矩;而质疑声也逐年高涨:Erlang 之父 Joe Armstrong 在 2009 年的《Coders at Work》访谈里留下著名毒舌——“面向对象语言的问题在于它们随身携带的隐式环境。你想要一根香蕉,结果拿到的是一只举着香蕉的猩猩和整个丛林。”Clojure 之父 Rich Hickey 在 2011 年 Strange Loop 大会的《Simple Made Easy》把批评推向方法论层面;游戏行业那边,Mike Acton 在 CppCon 2014 的《Data-Oriented Design and C++》演讲直指 OOP 的内存布局对缓存不友好。新一代语言的用脚投票更彻底:Go 从语言层面取消了继承,Rust 没有传统类继承,Apple 在 WWDC 2015 干脆为 Swift 推出了“面向协议编程”宣言。
把视频放回这条六十年线索里,可以给四根支柱分别标上可信度。
最扎实:封装与抽象。从 Parnas 1972 到今天,信息隐藏是软件工程五十年反复验证的共识,几乎找不到反方。Mosh 对这两条的“收益注脚”准确、克制,学理上完全站得住。
需要打折:继承。视频继承了 C++/Java 教学正典的叙事,把“消除冗余”当作继承的默认美德。但正如第五节所示,GoF 同年在书里就劝你优先组合,脆弱基类问题是工程界实打实的血泪史,Go 与 Rust 更是直接从语言层面否决了深继承。公平地说,这是入门课时长所限的取舍——但读者必须知道:“继承消除冗余”是四条注脚里唯一被现代主流大规模修正的一条,深继承树在今天的代码评审里更接近红旗而非美德。
需要上下文:多态重构 switch/case。当分支只有两三种、且极少变化时,一个直白的 switch 往往比“一个接口+多个实现类”更简单。社区对“接口污染”的批评由来已久——为多态而多态,会造出一堆只有一个实现的接口。多态的正确打开方式是“分派逻辑确实复杂且会增长”的场景。
框架本身也要打折:“四大支柱”是教学约定,不是正式定义。它是 C++/Java 教学传统提炼出的口诀,在 Kay 的原始思想里根本不存在这个清单——他心中的核心是消息传递与生物隐喻。把四支柱当成“OOP 的全部”,等于把地图当成了疆域。此外,桌面控件教学案例与真实系统的并发、持久化、性能关切距离很远,性能敏感领域(如游戏引擎)早已转向数据导向设计——这些边界,十三分钟量级的入门片没有义务讲,但“看完等于看完视频还多懂一层”的读者应该知道。
第一,把四条收益注脚变成代码评审清单。下次 review 代码时按四步扫一遍:看到 public 字段裸奔,问一句“封装呢”;看到接口暴露了一打方法而调用方只用两个,问一句“抽象呢”;看到三层以上的继承链,问一句“为什么不用组合”;看到按类型分派的巨型 switch/case,问一句“该上多态了吗”。四句问话,就是这条视频最实用的遗产。
第二,用收益倒推设计,而不是用概念套设计。Mosh 的四条注脚反过来用就是设计纪律:动手加任何抽象之前,先用一句话说清“我要降低哪类复杂度、隔离哪个变化”。说不出这句收益句,就不该加抽象——这能帮你避开比缺抽象更常见的病:过度设计。
第三,给自己排一个两周进阶路径。正典一侧:Parnas 1972 论文 → 《设计模式》第一章 → 里氏替换原则原文;反方一侧:Armstead 访谈《Coders at Work》的 OOP 章节、Mike Acton 的 CppCon 2014 演讲。正反两头各看一遍,你对 OOP 的理解就会从“背下四大支柱”升级为“知道它从哪来、擅长什么、败在哪”。
flowchart TD
A[过程式代码失控] --> B[类:数据与行为打包]
B --> C[对象:蓝图造出的实例]
C --> D[封装:藏住内部状态]
C --> E[抽象:只露必要接口]
C --> F[继承:is-a消除冗余]
C --> G[多态:同消息不同回应]
D --> H[复杂度有地方可藏]
E --> I[变化被隔离在膜内]
F --> J[代价:脆弱基类问题]
G --> K[重构丑陋的switch]
J --> L[药方:组合优于继承]
H --> M[四支柱是入门地图<br/>不是疆域]
I --> M
K --> M
L --> M
本文由「51学通信」技术团队出品。51学通信由通信行业18年老兵爱卫生(微信ID: gprshome201101)维护,聚焦5G/6G核心网、3GPP标准解读、通信前沿技术深度分析。 出版作品有《5G核心网原理与实践》《IMS原理与实践》等4本通信专业书籍。知识星球「51学通信」提供深度技术答疑和行业洞察。
[!tip] 51学通信知识星球 星主:爱卫生(微信:gprshome201101)——公众号「51学通信」创办者,19 年通信行业运维与讲师经验,著有《GPRS网络信令实例详解》《EPC原理与实践》《5G核心网原理与实践》三本纸质书(各大电商平台有售)。 星球定位:深耕 5G 核心网、IMS、NFV/AI、云原生等 ICT 领域,主打运维岗位与信令分析。 当前规模:5200 篇主题 / 990 个回答,198 元/年。 加入福利:加入星球后请加爱卫生微信,拉您进知识星球年度陪伴与答疑群——不限量回复您的各种问题,另有群内分享。 AI 加持:51学通信知识星球已作为 skill 接入 WorkBuddy,使用 deepseek-4-flash 在海量星球帖子中精准找贴、找视频、找 FAQ 和案例,做总结、找文档和 PPT 等场景全覆盖。
